使用事件对象(重叠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);
}

浙公网安备 33010602011771号