18,356
社区成员
发帖
与我相关
我的任务
分享
#include "stdafx.h"
#include <iostream>
#include <tchar.h>
#include <WINSOCK2.H>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#define MSGSIZE 1024
#define PORT 10000
typedef struct
{
WSAOVERLAPPED overlap;
WSABUF Buffer;
char szMessage[MSGSIZE];//
DWORD NumberOfBytesRecvd;
DWORD Flags;
SOCKET sClient;
}PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;
void CALLBACK CompletionROUTINE(DWORD dwError,
DWORD cbTransferred,
LPWSAOVERLAPPED lpOverlapped,
DWORD dwFlags)
{
LPPER_IO_OPERATION_DATA lpPerIOData = (LPPER_IO_OPERATION_DATA)lpOverlapped;
SOCKET sock=lpPerIOData->sClient;
if (dwError != 0 || cbTransferred == 0)
{
// Connection was closed by client
closesocket(lpPerIOData->sClient);
printf("一个客户退出 socket id:%d\r\n",lpPerIOData->sClient);
//释放客户对应的结构内存
delete lpPerIOData;
lpPerIOData=NULL;
}
else
{
printf("recv sock:%d size:%d\n",sock,cbTransferred);
//在这里处理接收的数据,然后发送...并重置这个客户socket异步接收操作..
//lpPerIOData->szMessage[cbTransferred] = '\0';
//send(lpPerIOData->sClient, lpPerIOData->szMessage, cbTransferred, 0);
// Launch another asynchronous operation
memset(&lpPerIOData->overlap, 0, sizeof(WSAOVERLAPPED));
lpPerIOData->Buffer.len = MSGSIZE;
lpPerIOData->Buffer.buf = lpPerIOData->szMessage;
WSARecv(lpPerIOData->sClient,
&lpPerIOData->Buffer,
1,
&lpPerIOData->NumberOfBytesRecvd,
&lpPerIOData->Flags,
&lpPerIOData->overlap,
CompletionROUTINE);
}
}
void GetError(DWORD error) //返回错误信息
{
switch(error)
{
case WSANOTINITIALISED:
printf("初始化错误\r\n");
break;
case WSAENOTCONN:
printf("对方没有启动\r\n");
break;
case WSAEWOULDBLOCK :
printf("对方已经关闭\r\n");
break;
case WSAECONNREFUSED:
printf("对方没打开端口\r\n");
break;
case WSAENOTSOCK:
printf("在一个非套接字上尝试了一个操作\r\n");
break;
case WSAEADDRINUSE:
printf("特定的地址已在使用中\r\n");
break;
case WSAECONNRESET:
printf("与主机的连接被关闭\r\n");
break;
default:
printf("一般错误,连接出现异常断开\r\n");
}
}
int main()
{
WSADATA wsaData;
SOCKET sListen;
SOCKADDR_IN local, client;
int iaddrSize = sizeof(SOCKADDR_IN);
// Initialize Windows Socket library
int ret= WSAStartup(0x0202, &wsaData);
if(ret!=0)
{
printf("socket WSAStartup Error!\r\n");
return 1;
}else printf("socket WSAStartup OK!\r\n");
// Create listening socket
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(PORT);
//绑定一个套接字到本机的地址
ret= bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));
if(ret == SOCKET_ERROR)
{ //绑定错误
printf("Binding Error\r\n");
return FALSE;
}
// Listen
ret= listen(sListen, 3);
if(ret==SOCKET_ERROR)
{
printf("listen失败 错误原因:",ret=WSAGetLastError());
GetError(ret);
return false ;
}
printf("listen OK!\r\nWaiting Client Connect\n");
while (TRUE)
{
// Accept a connection
LPPER_IO_OPERATION_DATA lpPerIOData = NULL;
SOCKET g_sNewClientConnection;
g_sNewClientConnection = accept(sListen, (struct sockaddr *)&client, &iaddrSize);
// Launch an asynchronous operation for new arrived connection
lpPerIOData=new PER_IO_OPERATION_DATA();
lpPerIOData->Buffer.len = MSGSIZE;
lpPerIOData->Buffer.buf = lpPerIOData->szMessage;
lpPerIOData->sClient = g_sNewClientConnection;
ret= WSARecv(lpPerIOData->sClient,//客户socket
&lpPerIOData->Buffer, //存放接收数据的
1, //dwBufferCount [in] Number of WSABUF structures in the lpBuffers array.
&lpPerIOData->NumberOfBytesRecvd,//存放接收数据的字节数
&lpPerIOData->Flags,
&lpPerIOData->overlap,
CompletionROUTINE);
//如果接收的数据超过MSGSIZE 系统就会多次调用CompletionROUTINE,直到接收完..
printf("Accepted client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
}
}