想作为大约千个客户端的一个UDP包的服务器来使用,不知道是否合适?UDP包接受后只要经过一点点的数据处理就行了,不需要返回信息给客户端,不知这样的性能是否可以呢?
初学网络编程,高手有什么建议,请提出来,谢谢!#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <iostream>
using namespace std;
void init()
{
WSADATA wsaData;
if( WSAStartup(MAKEWORD(2,2), &wsaData) < 0)
{
cout<<"wsastartup error!"<<endl;
exit(1);
}
}
int main(int argc, char* argv[])
{
init();
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sock == SOCKET_ERROR)
{
cout<<"sock error!"<<endl;
return 0;
}
SOCKADDR_IN sin;
sin.sin_addr.S_un.S_addr = inet_addr("10.10.80.80");
sin.sin_family = AF_INET;
sin.sin_port = htons(4567); if(bind(sock, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
cout<<"bind error!"<<endl;
return 0;
} WSAOVERLAPPED ol;
HANDLE hEvent;
WSABUF wsaBuf;
DWORD nRecv;
DWORD bFlag = 0;
DWORD nRet; char buf[512] = {'\0'};
SOCKADDR_IN from;
int fromLen = sizeof(SOCKADDR_IN);
hEvent = WSACreateEvent();
wsaBuf.buf = buf;
wsaBuf.len = 512;
memset(&ol, 0, sizeof(WSAOVERLAPPED));
ol.hEvent = hEvent; while(true)
{
nRet = WSARecvFrom(sock, &wsaBuf, 1, &nRecv, &bFlag, (sockaddr*)&from, &fromLen, &ol, NULL);
if (nRet != 0) 

if (WSAGetLastError() != WSA_IO_PENDING) 
{
cout<<"wsarecv error"<<endl;
return 0;
}
else
{
WSAResetEvent(hEvent);
nRet = WaitForSingleObject(hEvent, INFINITE);
if(nRet == WAIT_FAILED)
{
cout<<"wait failed!"<<endl;
}
cout<<"data:"<<wsaBuf.buf<<" from:"<<inet_ntoa(from.sin_addr)<<" port: "<<ntohs(sin.sin_port)<<endl;
}
}
}
return 0;
}

解决方案 »

  1.   

    我前几天写了一个WIN32服务程序,其中用到了Overlapped I/O模型来实现网络通讯,总结了一下,看对你有没有帮助。另外,建议你将“inet_addr("10.10.80.80"),sin.sin_port = htons(4567);”中的IP地址和端口号设为宏,这样修改起来方便些,“wsaBuf.len = 512;”中的512也可以这样做。
    采用Overlapped I/O模型编程一般要下面几步:
    1) 为套接字创建一个WSAOVERLAPPED结构,并为该结构分配一个事件对象句柄。
    也将事件对象句柄分配给一个事件数组,以便稍后由WSAWaitForMultipleEvents函数使用。
    2) 在套接字上投递一个异步WSARecv请求,指定参数为WSAOVERLAPPED结构。
    3) 使用步骤1)的事件数组,调用WSAWaitForMultipleEvents函数,并等待与重叠调用关
    联在一起的事件“触发”。
    4) WSAWaitForMultipleEvents函数完成后,针对事件数组,调用WSAResetEvent(重设
    事件)函数,从而重设事件对象,并对完成的重叠请求进行处理。
    5) 使用WSAGetOverlappedResult函数,判断重叠调用的返回状态是什么。
    6) 在套接字上投递另一个重叠WSARecv请求。
    7) 重复步骤3~6。
    程序框架如下:#define SOCKET_READ_DATA_BUFSIZE 4096
    DWORD WINAPI  ReceiveData()
    {
       // 定义并初始化相关变量
       WSABUF  wsabuf;
       unsigned char ReadBuf[SOCKET_READ_DATA_BUFSIZE]; //缓冲区定义
       WSAEVENT EventArray[2]; //即步骤1中的事件数组
       WSAOVERLAPPED ReceiveOverlapped; 
       DWORD Flags,BytesTransferred; 
       ZeroMemory(&ReceiveOverlapped, sizeof(WSAOVERLAPPED));
       EventArray[0] = WSACreateEvent();
       EventArray[1] =terminateEvent;
       ReceiveOverlapped.hEvent = EventArray[0];//为WSAOVERLAPPED结构分配 一个事件对象句柄
       wsabuf.len = SOCKET_READ_DATA_BUFSIZE;//设置接收缓冲区
       wsabuf.buf = (char *)ReadBuf;
       // 调用WSARecv 将数据接收到wsabuf
       WSARecv (m_hSocket,&wsabuf, 1,&BytesTransferred,&Flags,   &ReceiveOverlapped,NULL)
      // 处理异步接收
     while (TRUE) 
     {
      // 等待overlapped I/O 调用的完成
    Index = WSAWaitForMultipleEvents(2, EventArray, FALSE,   WSA_INFINITE, FALSE);
    Index -= WSA_WAIT_EVENT_0 ;
    //重设事件
    WSAResetEvent(EventArray[Index ]);
    switch (Index)
    {
      case 0:
               // 判断重叠调用的返回状态
      WSAGetOverlappedResult(m_hSocket, &ReceiveOverlapped,  &BytesTransferred, FALSE, &Flags);
      //此处应加入错误处理
      ParseFunction(ReadBuf, BytesTransferred); //处理接收到的数据
      // 重设Flag及overlapped结构
      Flags[Index] = 0;
      ZeroMemory(&ReceiveOverlapped, sizeof(WSAOVERLAPPED));
      ReceiveOverlapped.hEvent = EventArray[Index -  WSA_WAIT_EVENT_0];
     //重设接收缓冲区
     wsabuf.len = SOCKET_READ_DATA_BUFSIZE;
     wsabuf.buf = (char *)ReadBuf;
     //投递另一个重叠WSARecv请求
     WSARecv(m_hSocket, &wsabuf, 1, &BytesTransferred, &Flags,  &ReceiveOverlapped, NULL);
       break;
             case 1:
                //在我的程序中此处是处理一些清理工作。
                ........
                break;
    default:
       break;
    }// switch
      } //while
    return TRUE;
    }// ReceiveData