• 以纯重叠I/O方式实现回声服务器端(windows)


    服务器端:

    #include <stdio.h>
    #include <stdlib.h>
    #include <winsock2.h>
    
    #define BUF_SIZE 1024
    void CALLBACK ReadCompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD);
    void CALLBACK WriteCompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD);
    void ErrorHanding(char *msg);
    
    typedef struct 
    {
    SOCKET hClntSock;
    char buf[BUF_SIZE];
    WSABUF wsaBuf;
    } PER_IO_DATA, *LPPER_IO_DATA;
    
    int main(int argc, char *argv[])
    {
    WSADATA wsaData;
    SOCKET hLisnSock, hRecvSock;
    SOCKADDR_IN lisnAdr, recvAdr;
    LPWSAOVERLAPPED lpOvLp;
    DWORD recvBytes;
    LPPER_IO_DATA hbInfo;
    int mode = 1, recvAdrSz, flagInfo = 0;
    
    if (argc != 2)
    {
    printf("Usage: %s <port>
    ", 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);
    ioctlsocket(hLisnSock, FIONBIO, (u_long *)&mode); // for non-blocking mode socket
    
    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);
    while (1)
    {
    SleepEx(100, TRUE); // for alertable wait state
    hRecvSock = accept(hLisnSock, (SOCKADDR *)&recvAdr, &recvAdrSz);
    if (hRecvSock == INVALID_SOCKET)
    {
    if (WSAGetLastError() == WSAEWOULDBLOCK)
    continue;
    else
    ErrorHanding("accept() error");
    }
    puts("Client connected .....");
    
    lpOvLp = (LPWSAOVERLAPPED)malloc(sizeof(WSAOVERLAPPED));
    memset(lpOvLp, 0, sizeof(WSAOVERLAPPED));
    
    hbInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
    hbInfo->hClntSock = (DWORD)hRecvSock;
    (hbInfo->wsaBuf).buf = hbInfo->buf;
    (hbInfo->wsaBuf).len = BUF_SIZE;
    
    lpOvLp->hEvent = (HANDLE)hbInfo;
    WSARecv(hRecvSock, &(hbInfo->wsaBuf), 1, &recvBytes, (LPDWORD)&flagInfo, lpOvLp, ReadCompRoutine);
    }
    closesocket(hRecvSock);
    closesocket(hLisnSock);
    WSACleanup();
    return 0;
    } // end of main function
    
    void CALLBACK ReadCompRoutine(DWORD dwError, DWORD szRecvBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags)
    {
    LPPER_IO_DATA hbInfo = (LPPER_IO_DATA)(lpOverlapped->hEvent);
    SOCKET hSock = hbInfo->hClntSock;
    LPWSABUF bufInfo = &(hbInfo->wsaBuf);
    DWORD sendBytes;
    
    if (szRecvBytes == 0)
    {
    closesocket(hSock);
    free(lpOverlapped->hEvent);
    free(lpOverlapped);
    puts("Client disconnected .....");
    }
    else // echo!
    {
    bufInfo->len = szRecvBytes;
    WSASend(hSock, bufInfo, 1, &sendBytes, 0, lpOverlapped, WriteCompRoutine);
    }
    }
    
    void CALLBACK WriteCompRoutine(DWORD dwError, DWORD szSendBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags)
    {
    LPPER_IO_DATA hbInfo = (LPPER_IO_DATA)(lpOverlapped->hEvent);
    SOCKET hSock = hbInfo->hClntSock;
    LPWSABUF bufInfo = &(hbInfo->wsaBuf);
    DWORD recvBytes;
    int flagInfo = 0;
    WSARecv(hSock, bufInfo, 1, &recvBytes, (LPDWORD)&flagInfo, lpOverlapped, ReadCompRoutine);
    }
    
    void ErrorHanding(char *msg)
    {
    fputs(msg, stderr);
    fputc('
    ', stderr);
    exit(1);
    }

    客户端:

    #include <stdio.h>
    #include <stdlib.h>
    #include <winsock2.h>
    #define BUF_SIZE 1024
    void ErrorHandling(char *message);
    
    int main(int argc, char *argv[])
    {
    	WSADATA wsaData;
    	SOCKET hSocket;
    	SOCKADDR_IN servAdr;
    	char message[BUF_SIZE];
    	int strLen, readLen;
    
    	if (argc != 3)
    	{
    		printf("Usage: %s <IP> <port>
    ", argv[0]);
    		exit(1);
    	}
    	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    		ErrorHandling("WSAStartup() error!");
    
    	hSocket = socket(PF_INET, SOCK_STREAM, 0);
    	if (hSocket == INVALID_SOCKET)
    		ErrorHandling("socket() error");
    
    	memset(&servAdr, 0, sizeof(servAdr));
    	servAdr.sin_family = AF_INET;
    	servAdr.sin_addr.s_addr = inet_addr(argv[1]);
    	servAdr.sin_port = htons(atoi(argv[2]));
    
    	if (connect(hSocket, (SOCKADDR *)&servAdr, sizeof(servAdr)) == SOCKET_ERROR)
    		ErrorHandling("connect() error!");
    	else
    		puts("Connected ..........");
    
    	while (1)
    	{
    		fputs("Input message(Q to quit): ", stdout);
    		fgets(message, BUF_SIZE, stdin);
    		if(!strcmp(message, "q
    ") || !strcmp(message, "Q
    "))
    			break;
    
    		strLen = strlen(message);
    		send(hSocket, message, strLen, 0);
    		readLen = 0;
    		while (1)
    		{
    			readLen += recv(hSocket, &message[readLen], BUF_SIZE - 1, 0);
    			if (readLen >= strLen)
    				break;
    		}
    		message[strLen] = 0;
    		printf("Message from server: %s", message);
    	}
    
    	closesocket(hSocket);
    	WSACleanup();
    	return 0;
    }
    
    void ErrorHandling(char *message)
    {
    	fputs(message, stderr);
    	fputc('
    ', stderr);
    	exit(1);
    }
  • 相关阅读:
    40 宾语从句的连词
    unar解压rar,zip等文件
    Disable beep in WSL terminal on Windows 10 [closed]
    Collins COBUILD Advanced Learner’s Dictionary (Collins COBUILD Dictionaries for Learners)
    中小学语文示范诵读库
    自己打印标准五笔字型教材(86)
    赵元任《施氏食狮史》
    西班牙语学习资源
    为什么“能”?为什么“行”?为什么“好”?答案在这里!
    社会主义好
  • 原文地址:https://www.cnblogs.com/wisdomroc/p/11866843.html
Copyright © 2020-2023  润新知