想作为大约千个客户端的一个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;
}
初学网络编程,高手有什么建议,请提出来,谢谢!#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;
}
采用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