使用事件对象(重叠I/O)
发送端:
#include <stdio.h> #include <string.h> #include <winsock2.h> void ErrorHanding(char *msg); int main(int argc, char *argv[]) { WSADATA wsaData; SOCKET hSocket; SOCKADDR_IN sendAdr; WSABUF dataBuf; char msg[] = "Network is Computer!"; int sendBytes = 0; WSAEVENT evObj; WSAOVERLAPPED overlapped; if (argc != 3) { printf("Usage: %s <IP> <port>\n", argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) ErrorHanding("WSAStartUp() error!"); hSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); memset(&sendAdr, 0, sizeof(sendAdr)); sendAdr.sin_family = AF_INET; sendAdr.sin_addr.s_addr = inet_addr(argv[1]); sendAdr.sin_port = htons(atoi(argv[2])); if (connect(hSocket, (SOCKADDR *) &sendAdr, sizeof(sendAdr)) == SOCKET_ERROR) ErrorHanding("connect() error"); evObj = WSACreateEvent(); memset(&overlapped, 0, sizeof(overlapped)); overlapped.hEvent = evObj; dataBuf.len = strlen(msg) + 1; dataBuf.buf = msg; if (WSASend(hSocket, &dataBuf, 1, (DWORD *)&sendBytes, 0, &overlapped, NULL) == SOCKET_ERROR) { if (WSAGetLastError() == WSA_IO_PENDING) { puts("Background data send"); WSAWaitForMultipleEvents(1, &evObj, TRUE, WSA_INFINITE, FALSE); WSAGetOverlappedResult(hSocket, &overlapped, (DWORD *)&sendBytes, FALSE, NULL); } else { ErrorHanding("WSASend() error"); } } printf("Send data size: %d \n", sendBytes); WSACloseEvent(evObj); closesocket(hSocket); WSACleanup(); return 0; } // end of main function void ErrorHanding(char *msg) { fputs(msg, stderr); fputc('\n', stderr); exit(1); }
接收端:
#include <stdio.h> #include <string.h> #include <winsock2.h> #define BUF_SIZE 1024 void ErrorHanding(char *msg); int main(int argc, char *argv[]) { WSADATA wsaData; SOCKET hLisnSock, hRecvSock; SOCKADDR_IN lisnAdr, recvAdr; int recvAdrSz; WSABUF dataBuf; WSAEVENT evObj; WSAOVERLAPPED overlapped; char buf[BUF_SIZE]; int recvBytes = 0, flags = 0; if (argc != 2) { printf("Usage: %s <port>\n", argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) ErrorHanding("WSAStartUp() error!"); hLisnSock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); memset(&lisnAdr, 0, sizeof(lisnAdr)); lisnAdr.sin_family = AF_INET; lisnAdr.sin_addr.s_addr = htonl(INADDR_ANY); lisnAdr.sin_port = htons(atoi(argv[1])); if (bind(hLisnSock, (SOCKADDR *) &lisnAdr, sizeof(lisnAdr)) == SOCKET_ERROR) ErrorHanding("bind() error"); if (listen(hLisnSock, 5) == SOCKET_ERROR) ErrorHanding("listen() error"); recvAdrSz = sizeof(recvAdr); hRecvSock = accept(hLisnSock, (SOCKADDR *)&recvAdr, &recvAdrSz); evObj = WSACreateEvent(); memset(&overlapped, 0, sizeof(overlapped)); overlapped.hEvent = evObj; dataBuf.len = BUF_SIZE; dataBuf.buf = buf; if (WSARecv(hRecvSock, &dataBuf, 1, (DWORD *)&recvBytes, (DWORD *)&flags, &overlapped, NULL) == SOCKET_ERROR) { if (WSAGetLastError() == WSA_IO_PENDING) { puts("Background data receive"); WSAWaitForMultipleEvents(1, &evObj, TRUE, WSA_INFINITE, FALSE); WSAGetOverlappedResult(hRecvSock, &overlapped, (DWORD *)&recvBytes, FALSE, NULL); } else { ErrorHanding("WSARecv() error"); } } printf("Receive message: %s \n", buf); WSACloseEvent(evObj); closesocket(hRecvSock); closesocket(hLisnSock); WSACleanup(); return 0; } // end of main function void ErrorHanding(char *msg) { fputs(msg, stderr); fputc('\n', stderr); exit(1); }
使用Completion Routine函数
#include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #define BUF_SIZE 1024 void CALLBACK CompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD); void ErrorHandling(char *message); WSABUF dataBuf; char buf[BUF_SIZE]; int recvBytes = 0; int main(int argc, char *argv[]) { WSADATA wsaData; SOCKET hLisnSock, hRecvSock; SOCKADDR_IN lisnAdr, recvAdr; WSAOVERLAPPED overlapped; WSAEVENT evObj; int idx, recvAdrSz, flags = 0; if (argc != 2) { printf("Usage: %s <port>\n", argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) ErrorHandling("WSAStartup() error!"); hLisnSock = WSASocket(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); memset(&lisnAdr, 0, sizeof(lisnAdr)); lisnAdr.sin_family = AF_INET; lisnAdr.sin_addr.s_addr = htonl(INADDR_ANY); lisnAdr.sin_port = htons(atoi(argv[1])); if (bind(hLisnSock, (SOCKADDR *)&lisnAdr, sizeof(lisnAdr)) == SOCKET_ERROR) ErrorHandling("bind() error"); if (listen(hLisnSock, 5) == SOCKET_ERROR) ErrorHandling("listen() error"); recvAdrSz = sizeof(recvAdr); hRecvSock = accept(hLisnSock, (SOCKADDR *)&recvAdr, &recvAdrSz); if (hRecvSock == INVALID_SOCKET) ErrorHandling("accept() error"); memset(&overlapped, 0, sizeof(overlapped)); dataBuf.len = BUF_SIZE; dataBuf.buf = buf; evObj = WSACreateEvent(); if (WSARecv(hRecvSock, &dataBuf, 1, (DWORD *)&recvBytes, (DWORD *)&flags, &overlapped, CompRoutine) == SOCKET_ERROR) { if (WSAGetLastError() == WSA_IO_PENDING) puts("Background data receive"); } idx = WSAWaitForMultipleEvents(1, &evObj, FALSE, WSA_INFINITE, TRUE); if (idx == WAIT_IO_COMPLETION) puts("Overlapped I/O Completed"); else ErrorHandling("WSARecv() error"); WSACloseEvent(evObj); closesocket(hRecvSock); closesocket(hLisnSock); WSACleanup(); return 0; } void CALLBACK CompRoutine(DWORD dwError, DWORD szRecvBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags) { if (dwError != 0) { ErrorHandling("CompRoutine error"); } else { recvBytes = szRecvBytes; printf("Receive message: %s \n", buf); } } void ErrorHandling(char *message) { fputs(message, stderr); fputc('\n', stderr); exit(1); }