我们知道BSD Socket是标准的套接字规范,那么怎么在windows使用他们呢?
我们首先要引用<winsock2.h>和ws2_32.lib
然后,执行WSAStartup
#ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); iStatus = WSAStartup(wVersionRequested, &wsaData); if (iStatus != 0) { return 0; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return 0; } #endif
WSAStartup函数
int WSAStartup( _In_ WORD wVersionRequested, _Out_ LPWSADATA lpWSAData );
最后,执行关闭socket、清理工作
#ifdef _WIN32 closesocket(sockfd); WSACleanup(); #endif
WSACleanup函数
int WSACleanup(void);
以下程序在Win7 + VC10下编译通过
客户端程序:
// prjClt.cpp : Defines the entry point for the console application. // /** * Networking program is Win version with BSD Socket * Client side * * Author: xiaobin * Date: 2013-12-12 */ #include "stdafx.h" #ifdef _WIN32 #include <winsock2.h> #include <ws2tcpip.h> #pragma comment(lib, "ws2_32.lib") #else #include <sys/socket.h> #include <netinet/in.h> #include <arpa/in.h> #endif #define MAXLINE 254 #define DEFAULT_PORT 3293 int main(int argc, char* argv[]) { int sockfd; struct sockaddr_in servaddr; int iStatus; char *sendBuff = "this is test message!"; #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); iStatus = WSAStartup(wVersionRequested, &wsaData); if (iStatus != 0) { return 0; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return 0; } #endif if (argc != 2) printf("Usage: <IPaddress>> "); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) printf("socket error "); /* check Server address */ // inet_pton is win version - InetPton if (InetPton(AF_INET, argv[1], &servaddr.sin_addr) < 0) printf("inet_pton error for %s", argv[1]); /* Set serveraddr */ memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.S_un.S_addr = inet_addr(argv[1]); servaddr.sin_port = htons(DEFAULT_PORT); printf("%s%s%s ", "Connecting ", argv[1], " ..."); /* connect server */ iStatus = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); if ( iStatus < 0 ) { closesocket(sockfd); printf("connect error "); } printf("%s ", "Writing..."); /* Write data */ iStatus = send(sockfd, sendBuff, (int)strlen(sendBuff), 0); if (iStatus < 0) { printf("%s ", "write data error"); } printf("%s ", "Writed."); #ifdef _WIN32 closesocket(sockfd); WSACleanup(); #endif return 0; }
注意:InetPton函数只能在Windows Version >=6上实现!
服务器端程序:
// prjSrv.cpp : Defines the entry point for the console application. // /** * Networking program is Win version with BSD Socket * Server side * * Author: xiaobin * Date: 2012-12-18 23:35 */ #include "stdafx.h" #ifdef _WIN32 #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") #else #include <sys/socket.h> #include <netinet/in.h> #include <arpa/in.h> #endif #define DEFAULT_BUFLEN 128 #define DEFAULT_PORT 3293 int main(int argc, char* argv[]) { int srvSock, client; struct sockaddr_in addrSrv; int iStatus; int len; char buff[DEFAULT_BUFLEN]; #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); iStatus = WSAStartup(wVersionRequested, &wsaData); if (iStatus != 0) { return 0; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return 0; } #endif srvSock = socket(AF_INET, SOCK_STREAM, 0); addrSrv.sin_family = AF_INET; addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrSrv.sin_port = htons(DEFAULT_PORT); bind(srvSock, (struct sockaddr *)&addrSrv, sizeof(addrSrv)); listen(srvSock, 5); len = sizeof(struct sockaddr); while(1) { client = accept(srvSock, (struct sockaddr *)&addrSrv, (int *)&len); iStatus = recv(client, buff, DEFAULT_BUFLEN, 0); if (iStatus > 0) printf("%s ", buff); } #ifdef _WIN32 closesocket(client); closesocket(srvSock); WSACleanup(); #endif return 0; }
参考文献:
1. 《Unix 网络编程系列01》 - xiaobin
2. 《Unix 网络编程系列05》 - xiaobin
3. 《网络编程client和server》 - xiaobin
4. WSAStartup - Microsoft Developer Network
5. WSACleanup - Microsoft Developer Network
6. InetPton - Microsoft Developer Network