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?

 22
Author: rstackhouse, 2015-01-19

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ą typedefING 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.

 50
Author: GoBusto,
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.

 1
Author: GNSL,
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.

 1
Author: user58697,
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.

 0
Author: Alexander Saprykin,
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