16,471
社区成员
发帖
与我相关
我的任务
分享
//接收TCP连接
DWORD WINAPI ProcAccept(LPVOID lpParameter)
{
WSADATA wsaData;
SOCKET sListen, sClient;
SOCKADDR_IN local, client;
DWORD dwThreadId;
int iaddrSize = sizeof(SOCKADDR_IN);
//// Initialize Windows Socket library
WSAStartup(0x0202, &wsaData);
// Create listening socket
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//// Bind
local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(PORT);
bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));
// Listen
listen(sListen, 64);//3
// Create worker thread
CreateThread(NULL, 0, WorkerThread, lpParameter, 0, &dwThreadId);
HANDLE hSendCmd = (HANDLE)::CreateThread(NULL,0,ProcSendCmd,lpParameter,0,NULL);
while (!g_theadNET.exit)
{
// Accept a connection
sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);
g_CliSocketArr[g_iTotalConn] = sClient;
g_mapAddr.SetAt(sClientIP,g_iTotalConn);
//通过两种方式得到
// Allocate a PER_IO_OPERATION_DATA structure
g_pPerIODataArr[g_iTotalConn] = (LPPER_IO_OPERATION_DATA)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(PER_IO_OPERATION_DATA));
g_pPerIODataArr[g_iTotalConn]->Buffer.len = MSGSIZE; //接收缓冲长度
g_pPerIODataArr[g_iTotalConn]->Buffer.buf = g_pPerIODataArr[g_iTotalConn]->szMessage; //接收缓冲区域
//创建接收数据事件,绑定该socket
g_CliEventArr[g_iTotalConn] = g_pPerIODataArr[g_iTotalConn]->overlap.hEvent = WSACreateEvent();
// 异步该socket接收数据,即立刻返回,等待事件信号状态。
WSARecv(
g_CliSocketArr[g_iTotalConn],
&g_pPerIODataArr[g_iTotalConn]->Buffer,
1,
&g_pPerIODataArr[g_iTotalConn]->NumberOfBytesRecvd,
&g_pPerIODataArr[g_iTotalConn]->Flags,
&g_pPerIODataArr[g_iTotalConn]->overlap,
NULL);
g_iTotalConn++; //连接数加1
}
closesocket(sListen);
//////////////////////////
WSACleanup();
return 0;
}
//接收TCP连接数据
DWORD WINAPI WorkerThread(LPVOID lpParam)
{
CMainFrame* pMain=(CMainFrame*)lpParam;
///////////////////////////////////////////
int ret, index;
DWORD cbTransferred;
while (!g_theadNET.exit)
{
ret = WSAWaitForMultipleEvents(g_iTotalConn, g_CliEventArr, FALSE, 1000, FALSE); //等待事件信号,1s超时
if (ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT)
{
continue;
}
index = ret - WSA_WAIT_EVENT_0; //取信号事件的索引号
WSAResetEvent(g_CliEventArr[index]); //将事件重置
WSAGetOverlappedResult( //返回指定套接口上一个重叠操作的结果。
g_CliSocketArr[index], //调用重叠操作时socket
&g_pPerIODataArr[index]->overlap, //指向调用重叠操作时指定的WSAOVERLAPPED结构
&cbTransferred, //接收实际数据长度
TRUE, //指定函数是否等待挂起的重叠操作结束
&g_pPerIODataArr[g_iTotalConn]->Flags); //该变量存放完成状态的附加标志位
if (cbTransferred == 0) //接收为数据长度为0,表示socket已经被关闭
{
// The connection was closed by client
Cleanup(index);
}
else
{
BYTE arr[MSGSIZE];
for(int i=0;i<cbTransferred;i++)
{
arr[i]=(BYTE)g_pPerIODataArr[index]->szMessage[i];
//printf("%02X ",arr[i]);
}
// Launch another asynchronous operation
WSARecv(
g_CliSocketArr[index],
&g_pPerIODataArr[index]->Buffer,
1,
&g_pPerIODataArr[index]->NumberOfBytesRecvd,
&g_pPerIODataArr[index]->Flags,
&g_pPerIODataArr[index]->overlap,
NULL);
}
}
return 0;
}
//服务器端发送客户端线程
DWORD WINAPI ProcSendCmd(LPVOID lpParameter)
{
while(true)
{
if(有数据)
{
int index=查找对应的连接;
int a=send(g_CliSocketArr[index], (char*)buf,len, 0);
}
}
}
//程序在运行时发现,如果用send函数发送,则会丢失数据,查看返回值 也标示发送成功了,但就是没收到。
如果用 WSASend发送,重叠结构用接收时候生成的同一结构,则客户端不发送后,服务器端还有数据,请问是什么原因??
int a=WSASend(g_CliSocketArr[index],&DataBuf,1,&SendBytes,0,&g_pPerIODataArr[index]->overlap,NULL);