初学Winsock编程..
准备从UDP下手..
一开始sendto啥的函数很容易.
recvfrom啥的也很容易
但是...某次我没注意.吧server关了..然后client就准备等到天荒地老去了
然后纠结了下.找了几个同事问问..
发现WSAEnumNetworkEvents这玩意不仅仅是多线程下的处理.还可以用于现在这种加超时的sock
就不用再单独给socket设置个超时时间了
代码如下
虽然是个很简单的东西.但是还是希望大家不笑我哇.
与网上随处可见的超时的区别就是这个没给socket去set一个timeout,而是靠wait一个绑定到该socket后的wsaevent
#include <Winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
BOOL SendUdpAndRecvTimeOut(PCHAR ServerIP,USHORT ServerPort,PVOID SendDate,ULONG SendSize,PVOID RecvDate,ULONG RecvSize,ULONG Timeout)
{
WSADATA wsaData;
ZeroMemory(&wsaData,sizeof(WSADATA));
if (WSAStartup(MAKEWORD(1,1), &wsaData) != 0)//初始化WSA
{
return FALSE;
}
SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);//创建socket,SOCK_DGRAM代表UDP
if(sockSrv == INVALID_SOCKET)
{
WSACleanup();
return FALSE;
}
SOCKADDR_IN addr_in;
ZeroMemory(&addr_in,sizeof(addr_in));
addr_in.sin_family = AF_INET;
addr_in.sin_addr.S_un.S_addr = inet_addr(ServerIP);//填写对端IP
addr_in.sin_port = htons(ServerPort);
int ret = sendto(sockSrv,(PCHAR)SendDate,SendSize,NULL,(struct sockaddr*)&addr_in,sizeof(addr_in));
if (ret == SOCKET_ERROR)//发送失败则返回
{
closesocket(sockSrv);
WSACleanup();
return FALSE;
}
WSAEVENT SockEvent = WSACreateEvent();
if (WSAEventSelect(sockSrv,SockEvent,FD_READ|FD_OOB) != 0)//将sockt与event关联.当socket发生第三个参数的事件时候将setevent
{
closesocket(sockSrv);
WSACleanup();
return FALSE;
}
if (WSA_WAIT_EVENT_0 != WSAWaitForMultipleEvents(1,&SockEvent,TRUE,Timeout,FALSE))
{
WSACloseEvent(SockEvent);
closesocket(sockSrv);
WSACleanup();
return FALSE;//不是成功则返回失败
}
WSANETWORKEVENTS NetworkEvents;
WSAEnumNetworkEvents(sockSrv,SockEvent,&NetworkEvents);//获取触发event的操作类型
//WSAResetEvent(SockEvent);
WSACloseEvent(SockEvent);//关闭event
sockaddr addr_out;
ZeroMemory(&addr_out,sizeof(addr_out));
switch(NetworkEvents.lNetworkEvents)//根据触发类型操作
{
case FD_READ: //与00b用一个函数
case FD_OOB:
int sizeofoutadd = sizeof(addr_out);
if (SOCKET_ERROR == recvfrom(sockSrv,(PCHAR)RecvDate,RecvSize,MSG_PEEK,&addr_out,&sizeofoutadd))
{
int errod = WSAGetLastError();
closesocket(sockSrv);
WSACleanup();
return FALSE;
}
break;
}
closesocket(sockSrv);
WSACleanup();
return TRUE;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)