UDP-事件模型

#pragma once
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include "winsock2.h"

#include <string>
//#include <winsock2.h>
#include <iostream>
#include <mswsock.h>


#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"Mswsock.lib")

using namespace std;

struct fd_es_set //事件模型
{
    UINT count;
    SOCKET socketServer;
    HANDLE event;
};
#include "main.h"
fd_es_set allsock;

LONG64 write_error()
{
    return 1;
}


void clear()
{


    /*释放整个结构体,可能有些事件和socket已经被释放过了,不影响*/
    {

        //释放stocket
        closesocket(allsock.socketServer);
        //关闭事件对象
        WSACloseEvent(allsock.event);
    }

    //清理网络库
    WSACleanup();
}


int create(const char* ServerIpAdress)
{
	/*接收信息,主要是高低版本信息*/
	WSADATA wsaData;

	/* 使用Windef.h中声明的MAKEWORD(低字节、高字节)宏 */
	WORD wVersionRequested = MAKEWORD(2, 2);


	/*启用网络链接库,调用的封装库命令*/
	if (0 != WSAStartup(wVersionRequested, &wsaData))
	{
		write_error();
		return -1;
	}


    /*确认WinSock DLL支持2.2*/

    /*请注意,如果DLL支持更高版本*/

    /*除了2.2之外,它还将返回*/

    /*wVersion中的2.2,因为这是我们*/

    /*请求*/

    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */
        write_error();
        //清理网络库
        WSACleanup();
        return -1;
    }

    //创建绑定到特定传输服务提供程序的套接字。 创建网络类型 tcp或者upd
    allsock.socketServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (INVALID_SOCKET == allsock.socketServer)
    {
        write_error();
        //清理网络库
        WSACleanup();
        return -1;
    }

    //设置sockaddr结构
    sockaddr_in saServer;
    saServer.sin_family = AF_INET;
    saServer.sin_addr.s_addr = INADDR_ANY;// inet_addr(ServerIpAdress);
    saServer.sin_port = htons(10000);//ntohs(saServer.sin_port)改回去

 
    //使用绑定侦听套接字     绑定IP和端口
  //sockaddr结构中的信息
    if (SOCKET_ERROR == bind(allsock.socketServer, (SOCKADDR*)&saServer, sizeof(saServer)))
    {
        string ret = to_string(WSAGetLastError());
        MessageBoxA(0, ret.c_str(), "error_bind", 0);
        //释放stocket
        closesocket(allsock.socketServer);
        //清理网络库
        WSACleanup();
        return -1;
    }




    /*创建一个套接字 事件*/
    allsock.event = WSACreateEvent();
    if (WSA_INVALID_EVENT == allsock.event)
    {
        string ret = to_string(WSAGetLastError());
        MessageBoxA(0, "error_WSACreateEventServer", ret.c_str(), 0);
        //释放stocket
        closesocket(allsock.socketServer);
        //清理网络库
        WSACleanup();
        return -1;
    }

    /*将服务器socket和事件绑定*/
    if (SOCKET_ERROR == WSAEventSelect(allsock.socketServer, allsock.event, FD_READ | FD_WRITE))
    {
        string ret = to_string(WSAGetLastError());
        MessageBoxA(0, "error_WSAEventSelecttServer", ret.c_str(), 0);
        //释放stocket
        closesocket(allsock.socketServer);
        //清理网络库
        WSACleanup();
        return -1;
    }


    while (1)
    {
        Sleep(3);

        {
            DWORD RET = 0;
            /*等待事件:有事件产生后返回对应事件的下标*/
            RET = WSAWaitForMultipleEvents(1, &allsock.event, false, WSA_INFINITE, false);
            /*返回错误*/
            if (WSA_WAIT_FAILED == RET)
            {
                string ret = to_string(WSAGetLastError());
                MessageBoxA(0, "error_WSAWaitForMultipleEvents", ret.c_str(), 0);
                continue;
            }
            /*等待超时检测*/


            /*枚举事件:获取事件类型,并重置其的信号*/
            WSANETWORKEVENTS GetlpNetworkEvents;
            if (SOCKET_ERROR == WSAEnumNetworkEvents(allsock.socketServer, allsock.event, &GetlpNetworkEvents))
            {
                string ret = to_string(WSAGetLastError());
                MessageBoxA(0, "error_WSAEnumNetworkEvents", ret.c_str(), 0);
                continue;
            }

            /*********FD_READ 可能是组合指令,故需要 & 判断*/
            if (GetlpNetworkEvents.lNetworkEvents & FD_READ)
            {
                if (0 == GetlpNetworkEvents.iErrorCode[FD_READ_BIT])
                {//正常处理
                    sockaddr_in ClientMsg = { 0 };

                    int ClientMsg_size = sizeof(ClientMsg);

                    char buff[548];
                    memset(buff, 0, sizeof(buff));

                    if (SOCKET_ERROR == recvfrom(allsock.socketServer, buff, sizeof(buff), 0, (sockaddr*)&ClientMsg, &ClientMsg_size))
                    {
                        continue;
                    }
                    printf("ClientIp:%d.%d.%d.%d:%d  \n Buff:%s\n\n",
                        ClientMsg.sin_addr.S_un.S_un_b.s_b1,
                        ClientMsg.sin_addr.S_un.S_un_b.s_b2,
                        ClientMsg.sin_addr.S_un.S_un_b.s_b3,
                        ClientMsg.sin_addr.S_un.S_un_b.s_b4,
                        ntohs(ClientMsg.sin_port),
                        buff);

                    char sendbuff[548] = "get";
                    if (SOCKET_ERROR == sendto(allsock.socketServer, sendbuff, strlen(sendbuff), 0, (sockaddr*)&ClientMsg, sizeof(ClientMsg)))
                    {
                        continue;
                    }
                }
                else
                {
                    continue;
                }
            }
        }
    }

    clear();

}




BOOL  WINAPI HANDLER_ROUTINE(_In_ DWORD CtrlType)
{
    switch (CtrlType)
    {
    case CTRL_CLOSE_EVENT:
    {
        clear();
    }
    default:
        break;
    }

    return true;
}


int main()
{
    //创建个回调监视控制台关闭
    SetConsoleCtrlHandler(HANDLER_ROUTINE, true);
    create("0");
	return 1;
}

由于UDP是无绑定通信故没有 ACCEPT和CLOSE,比较简单

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值