Gniazda krzyżowe [zamknięte]
Wiem, Windows nie używa gniazd UNIX, podczas gdy Mac OS. Do tego momentu moje oprogramowanie było wieloplatformowe bez żadnych zmian w kodzie. Ale teraz chcę, aby to zrobić jakąś komunikację sieciową. Wiem o gniazdach POSIX, ale nic Nie wiem o gniazdach Windows. Celem jest wdrożenie prostego wieloplatformowego serwera socket.
Czy mógłbyś mi wyjaśnić różnice między gniazdami POSIX i Winsock i jak mogę pisać wieloplatformowy kod sieciowy?
4 answers
WinSock kontra gniazda POSIX
Gniazda Winsock i POSIX działają w podobny sposób - głównie dlatego, że Gniazda Windows były pierwotnie oparte na kodzie z BSD:
Chociaż te własnościowe pochodne BSD zostały w dużej mierze zastąpione przez systemy UNIX System V Release 4 i OSF/1 w latach 90. (oba zawierają kod BSD i są podstawą innych współczesnych systemów uniksowych), późniejsze wydania BSD stanowiły podstawę dla kilku projekty programistyczne typu open source, np. FreeBSD, OpenBSD, NetBSD, Darwin czy PC-BSD, które są w trakcie realizacji. W 2007 roku firma Apple ogłosiła, że w 2008 roku firma Apple wprowadziła do swojej oferty system operacyjny Microsoft Windows, oparty na technologii TCP/IP (IPv4).
Jest jednak kilka rzeczy, z którymi musisz poradzić sobie inaczej, jeśli chcesz napisać kod "socket-library-agnostyc".
Uwaga: poniższe przykłady zostały przetestowane przy użyciu Code:: Blocks i GCC na Windows XP (x86) i Debian Testing (AMD64).
Nagłówek i pliki lib są różne
Musisz dołączyć różne pliki nagłówkowe w zależności od tego, czy używasz systemu Windows, czy nie:
#ifdef _WIN32
/* See http://stackoverflow.com/questions/12765743/getaddrinfo-on-win32 */
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501 /* Windows XP. */
#endif
#include <winsock2.h>
#include <Ws2tcpip.h>
#else
/* Assume that any non-Windows platform uses POSIX-style sockets instead. */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h> /* Needed for getaddrinfo() and freeaddrinfo() */
#include <unistd.h> /* Needed for close() */
#endif
Musisz również połączyć się z plikiem Ws2_32
lib w systemie Windows.
WinSock wymaga inicjalizacji i czyszczenia.
Poniższe funkcje ilustrują jak można zainicjować WinSock v1. 1 i posprzątaj po sobie:
int sockInit(void)
{
#ifdef _WIN32
WSADATA wsa_data;
return WSAStartup(MAKEWORD(1,1), &wsa_data);
#else
return 0;
#endif
}
int sockQuit(void)
{
#ifdef _WIN32
return WSACleanup();
#else
return 0;
#endif
}
Uchwyty gniazd są niepodpisane na Winsock]}
Dla gniazd w stylu POSIX, możesz po prostu użyć int
do przechowywania uchwytu gniazda. Nieprawidłowe gniazda są oznaczone wartością ujemną.
Jednakże, gniazda WinSock są niepodpisanymi liczbami całkowitymi , ze specjalną stałą (INVALID_SOCKET
) używaną zamiast liczb ujemnych.
Możesz wyodrębnić różnice za pomocą typedef
ING SOCKET jako int
w POSIX i ukryć zaznaczenie "poprawne gniazdo" za makrem lub funkcja.
Gniazda są zamknięte inaczej
Poniższa funkcja ilustruje różnice:
/* Note: For POSIX, typedef SOCKET as an int. */
int sockClose(SOCKET sock)
{
int status = 0;
#ifdef _WIN32
status = shutdown(sock, SD_BOTH);
if (status == 0) { status = closesocket(sock); }
#else
status = shutdown(sock, SHUT_RDWR);
if (status == 0) { status = close(sock); }
#endif
return status;
}
Ogólnie rzecz biorąc, są dość podobne.
Jeśli trzymasz się" zwykłych " funkcji (takich jak send()
lub recv()
) i unikasz rzeczy specyficznych dla platformy (takich jak WSAWaitForMultipleEvents()
) więc nic Ci nie będzie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-21 16:53:43
Istnieje wiele bibliotek i zestawów narzędzi, które obsługują gniazda międzyplatformowe, w zależności od tego, co robisz, możesz użyć (aby wymienić tylko kilka):
- openssl
- apache portable runtime
- libtcl
Jeśli nie chcesz mieć zależności od zewnętrznej biblioteki, wszystkie powyższe pakiety mają dość liberalne licencje, więc możesz użyć ich kodu jako odniesienia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-19 17:02:53
Zwykłe gniazda (te z rodziny adresów AF_INET), które są potrzebne do zbudowania serwera gniazd, są jednakowo obsługiwane na wszystkich platformach.
Nie myl ich z gniazdami Uniksowymi ( tymi z rodziny adresów AF_UNIX) - takie gniazda są bardzo specyficzne dla świata Uniksa i są używane do bardzo konkretnych celów. Nigdy nie potrzebowałbyś ich do prostej aplikacji serwera socket.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-19 18:09:06
Mogę również zasugerować bibliotekę plibsys : działa zarówno na systemach Windows, jak i UNIX (pełna lista znajduje się na stronie projektu) z różnymi kompilatorami. Obsługuje IPv4 i IPv6. Ma testy, w których można zobaczyć przykłady użycia. Sama Biblioteka jest lekka i przenośna.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-13 19:51:20