其他分享
首页 > 其他分享> > 使用事件对象(重叠I/O)

使用事件对象(重叠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 (WSASend(hRecvSock, &dataBuf, 1, (DWORD *)&recvBytes, 0, &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);
}

标签:overlapped,evObj,对象,hLisnSock,事件,lisnAdr,error,SOCKET,重叠
来源: https://www.cnblogs.com/wisdomroc/p/11864517.html