100分求完成端口发送数据的方法。先来先得 ^_^

时间:2021-12-25 23:50:17
DWORD __stdcall CCompletionPort::CompletionRoutine(LPVOID lParam)
{
HANDLE hCompletionPort  = (HANDLE)lParam;
BOOL bRet  = 0;
LPOVERLAPPED lpOverlapped  = NULL;
LPCompletionKey lpCompletionKey  = NULL;
LPOverlappedData lpOverlappedData = NULL;
DWORD dwNumOfBytes  = 0;
DWORD dwRecvBytes  = 0;
DWORD dwSendBytes  = 0;
DWORD dwFlags  = 0;
CDealWithMsg dealmsg;

for(;;)
{
bRet = GetQueuedCompletionStatus(
hCompletionPort,
&dwNumOfBytes, 
(LPDWORD)&lpCompletionKey, 
(LPOVERLAPPED*)&lpOverlappedData, 
INFINITE
);

if(bRet == false && &(lpOverlappedData->Overlapped) == NULL)
{
cout << "GetQueuedCompletionStatus error. Error code: " << GetLastError() << endl;
return 1;
}
else if(bRet == false && &(lpOverlappedData->Overlapped) != NULL)
{
cout << (unsigned int)lpCompletionKey->socket << " 非法退出" << endl;

if(closesocket(lpCompletionKey->socket) == SOCKET_ERROR)
{
cout << "关闭套接字失败" << endl;
}

GlobalFree(lpOverlappedData);
GlobalFree(lpCompletionKey);
}
else if(dwNumOfBytes == 0)
{
cout << (unsigned int)lpCompletionKey->socket << " 已关闭端口" << endl;

if(closesocket(lpCompletionKey->socket) == SOCKET_ERROR)
{
cout << "关闭套接字失败" << endl;
}

GlobalFree(lpOverlappedData);
GlobalFree(lpCompletionKey);

continue;
}
else
{
if(lpOverlappedData->bOperationType == RECV_POSTED)
{
CHicqMsg* phicqmsg = (CHicqMsg*)lpOverlappedData->wsaBuf.buf;
phicqmsg->SetSocket(lpCompletionKey->socket);

dealmsg.DealWithMsg(phicqmsg, lpOverlappedData);
}
else if(lpOverlappedData->bOperationType == SEND_POSTED)
{
}
// waitting next receive
dealmsg.RecvMsg(lpCompletionKey->socket, lpOverlappedData);
}

}

return 0;
}
CDealWithMsg是另外写出一个处理数据的类。
第一次发送数据,就会进入死循环,如果我只是收,就没有问题,我发时是用的
int CDealWithMsg::DealWithMsg(CHicqMsg* phicqmsg, LPOverlappedData lpOverlappedData)
{
CHsocket hsocket(phicqmsg->GetSocket());

switch(phicqmsg->GetCmd())
{
case HICQ_CMD_LOGIN:
if(!Login(phicqmsg->GetUserID(), phicqmsg->GetSocket(), hsocket.getremoteaddr(), 
hsocket.getremoteport(), phicqmsg->GetPassWord()))
{
phicqmsg->SetCmd(HICQ_CMD_LOGOUT);
phicqmsg->SetFlags(HICQ_FLAG_INVALID_USERNAME);

SendMsg(phicqmsg->GetSocket(), lpOverlappedData);
break;
}// login failed

// login success
cout << phicqmsg->GetUserID() << " has logined" << endl;

phicqmsg->SetCmd(HICQ_CMD_LOGIN);
phicqmsg->SetFlags(HICQ_FLAG_LOGIN_SUCCESS);

SendMsg(phicqmsg->GetSocket(), lpOverlappedData);
break;
      。。。。。
 }
int CDealWithMsg::SendMsg(SOCKET socket, LPOverlappedData lpOverlappedData)
{
DWORD dwSendBytes  = 0;
DWORD dwFlags  = 0;

ZeroMemory(&(lpOverlappedData->Overlapped), sizeof(OVERLAPPED));
lpOverlappedData->bOperationType = SEND_POSTED;

return WSASend(
socket,
&(lpOverlappedData->wsaBuf),
1, 
&dwSendBytes,
dwFlags, 
&(lpOverlappedData->Overlapped),
NULL
);
}

int CDealWithMsg::RecvMsg(SOCKET socket, LPOverlappedData lpOverlappedData)
{
DWORD dwSendBytes  = 0;
DWORD dwFlags  = 0;

ZeroMemory(&(lpOverlappedData->Overlapped), sizeof(OVERLAPPED));
lpOverlappedData->wsaBuf.len = MAXLEN;
lpOverlappedData->wsaBuf.buf = lpOverlappedData->buff;
lpOverlappedData->bOperationType = RECV_POSTED;

return WSARecv(
socket,
&(lpOverlappedData->wsaBuf),
1, 
&dwSendBytes,
&dwFlags, 
&(lpOverlappedData->Overlapped),
NULL
);
}
enum { ACCEPT_POSTED, RECV_POSTED, SEND_POSTED };

typedef struct st_CompletionKey
{
SOCKET socket;
}CompletionKey, *LPCompletionKey;

typedef struct st_OverlappedData
{
OVERLAPPED Overlapped;
WSABUF    wsaBuf;
char    buff[MAXLEN];
BOOL    bOperationType;
}OverlappedData,*LPOverlappedData;
谁能告诉我要怎么发数据啊,在服务器端,谢谢

17 个解决方案

#1


投递个wsaSend服务阿!

#2


我就是投的一个wsasend啊,可是不行,要是行,也就不会有这个贴子了:)

#3


如果把
DealWithMsg(...)里的
phicqmsg->SetCmd(HICQ_CMD_LOGIN);
phicqmsg->SetFlags(HICQ_FLAG_LOGIN_SUCCESS);
SendMsg(phicqmsg->GetSocket(), lpOverlappedData);
去掉,即不发消息,就没有问题。

#4


这是我一个WsaSend的处理,希望对你有用!


#define SENDOPTION 1
#define RECVOPTION 2


typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[DATA_BUFSIZE];
DWORD BytesSEND;
DWORD BytesRECV;
DWORD Option;
}PER_IO_OPERATION_DATA,*LPPER_IO_OPERATION_DATA;


int CServerSocket::SendMsg(SOCKET cliSocket,char *buf)
{
HANDLE ComPort=CompletionPort;
DWORD dwBytesTransferred;
DWORD dwBytesSend,dwBytesRecvd;
DWORD Flags=0;
PER_IO_OPERATION_DATA* PerIOData=new PER_IO_OPERATION_DATA;
PER_HANDLE_DATA* PerHandleData=new PER_HANDLE_DATA;

         Flags = 0;

         ZeroMemory(&(PerIOData->Overlapped), sizeof(OVERLAPPED));

 strncpy(PerIOData->Buffer ,"hello world",20);
         PerIOData->DataBuf.len = DATA_BUFSIZE;
         PerIOData->DataBuf.buf = PerIOData->Buffer;
PerIOData->Option=SENDOPTION;
         if (WSASend(cSocket[0], &(PerIOData->DataBuf), 1, &dwBytesSend, Flags,
            &(PerIOData->Overlapped), NULL) == SOCKET_ERROR)
         {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
               printf("WSARecv() failed with error %d\n", WSAGetLastError());
               return 0;
            }
         }
}

DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE ComPort=(HANDLE)CompletionPortID;
DWORD dwBytesTransferred;
DWORD dwBytesSend,dwBytesRecvd;
DWORD Flags=0;
LPPER_HANDLE_DATA PerHandleData;  
LPPER_IO_OPERATION_DATA PerIOData;
while(TRUE)
{
if(GetQueuedCompletionStatus(ComPort,&dwBytesTransferred,(LPDWORD)&PerHandleData,
(LPOVERLAPPED*)&PerIOData,INFINITE)==0)
{
int nErrorCode=GetLastError();
AfxMessageBox("GetQueue Failed");
return -1;
}
if(dwBytesTransferred==0)
{
closesocket(PerHandleData->Socket);
delete  PerIOData;
delete PerHandleData;
}
if(PerIOData->Option==SENDOPTION)
{
AfxMessageBox("Send SuccessFul");
continue;
}
}

#5


HunterForPig(留着口水的猪) :
很感谢你的回答,看完你的代码,似乎还是找不到答案,你能否把ServerWorkerThread里的代码贴全,或是把你整个程序发给我,谢谢!

hackangel_lili@yahoo.com.cn

#6


看看这个例子http://elssann.51.net/class.rar

#7


建议楼主看看wsasend返回值是什么。

#8


我在处理收到的消息时,又要发消息,那投下一个wsarecv是在wsasend之后还是之前啊
比如收到客户发来的消息请求得到好友列表,就要马上给他发好友列表。

#9


这个?猫王最精通

#10


stavck(关未明) :
你提供的不存在哦:)

#11


rabo(不哭死人): 你说的猫王是否为sevencat
QQ里倒是有他,但不常在线,哦,隐身了,明天请教一下:)

#12


其实关于WSASend的处理已经全了
下面那些代码是投递WSARecv请求!

#13


HunterForPig(留着口水的猪):
我发现我的程序现在可能就是wsasend & wsarecv没有投好,前几天搞好了,可我觉得有问题,改了一下,现以又有问题,我觉得以前那样不好,
能否把你的代码参考一下。

#14


#define PORT 5150
#define DATA_BUFSIZE 4096
#define SENDOPTION 1
#define RECVOPTION 2
CWinThread* pServerListenThread=NULL;
SOCKET lSocket,cSocket[64];
HANDLE CompletionPort;

DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID);
char BUF[4096];

typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[DATA_BUFSIZE];
DWORD BytesSEND;
DWORD BytesRECV;
DWORD Option;
}PER_IO_OPERATION_DATA,*LPPER_IO_OPERATION_DATA;

typedef struct
{
SOCKET Socket;
//SOCKADDR addr;
}PER_HANDLE_DATA,*LPPER_HANDLE_DATA;

CServerSocket::CServerSocket()
{
}
int CServerSocket::StartListen(UINT& Port)
{
m_nPort=Port;

WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
AfxMessageBox("Startup Failed");
return -1;
}




lSocket=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN servAddr;
servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
servAddr.sin_port=htons(Port);

int nRet=0;
if((nRet=bind(lSocket,(SOCKADDR*)&servAddr,sizeof(servAddr)))==SOCKET_ERROR)
{
AfxMessageBox("bind socket Error");
return -1;
}

//创建一完成端口,!

CompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);

SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);

for(int i=0;i<(int)SystemInfo.dwNumberOfProcessors*2;i++)//每个comio创建两个线程
{
HANDLE ThreadHandle;
if((ThreadHandle=CreateThread(NULL,0,ServerWorkerThread,CompletionPort,0,NULL))==NULL)
{
int errorCode=GetLastError();
return -1;
}
CloseHandle(ThreadHandle);
}

if(listen(lSocket,5)==SOCKET_ERROR)
{
AfxMessageBox("listen socket Failed");
return -1;
}

pServerListenThread=AfxBeginThread(_ServerListenThread,this);


}

UINT _ServerListenThread(LPVOID lParam)
{
CServerSocket *pServ=(CServerSocket*)lParam;
SOCKET clientSocket;
SOCKADDR_IN clientAddr;
PER_HANDLE_DATA *PerHandleData=NULL;;
PER_IO_OPERATION_DATA  *PerIOData=NULL;
DWORD Flags=0;
int addrLen=sizeof(SOCKADDR_IN);

int i=0;
while(TRUE)
{
clientSocket=accept(lSocket,(SOCKADDR*)&clientAddr,&addrLen);
if(clientSocket==SOCKET_ERROR)
{
int nErrorCode=GetLastError();
AfxMessageBox("Accept failed");
return -1;
}

cSocket[i]=clientSocket;
i++;
PerHandleData=new PER_HANDLE_DATA;
PerHandleData->Socket=clientSocket;
if(CreateIoCompletionPort((HANDLE)clientSocket,CompletionPort,(DWORD)PerHandleData,0)==NULL)
{
int nErrorCode=GetLastError();
AfxMessageBox("关联句柄与端口错误");
return -1;
}


PerIOData=new PER_IO_OPERATION_DATA;
ZeroMemory(&PerIOData->Overlapped ,sizeof(OVERLAPPED));
PerIOData->Option =RECVOPTION;

PerIOData->DataBuf.buf =BUF;
//PerIOData->DataBuf.buf =PerIOData->Buffer;  
PerIOData->DataBuf.len =DATA_BUFSIZE;
PerIOData->BytesRECV=0;
PerIOData->BytesSEND=0;
Flags=0;
if(WSARecv(clientSocket,&PerIOData->DataBuf,1,&PerIOData->BytesRECV,&Flags,
&PerIOData->Overlapped,NULL)==SOCKET_ERROR)
{
if(WSAGetLastError() != WSA_IO_PENDING) 
{
int nErrorCode=GetLastError();
AfxMessageBox("第一次投递WSARecv错误");
return -1;
}
}

}
return 0;
}
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE ComPort=(HANDLE)CompletionPortID;
DWORD dwBytesTransferred;
DWORD dwBytesSend,dwBytesRecvd;
DWORD Flags=0;
LPPER_HANDLE_DATA PerHandleData;  
LPPER_IO_OPERATION_DATA PerIOData;
while(TRUE)
{
if(GetQueuedCompletionStatus(ComPort,&dwBytesTransferred,(LPDWORD)&PerHandleData,
(LPOVERLAPPED*)&PerIOData,INFINITE)==0)
{
int nErrorCode=GetLastError();
AfxMessageBox("GetQueue Failed");
return -1;
}
if(dwBytesTransferred==0)
{
closesocket(PerHandleData->Socket);
delete  PerIOData;
delete PerHandleData;
}
if(PerIOData->Option==SENDOPTION)
{
AfxMessageBox("Send SuccessFul");
continue;
}
if(PerIOData->Option==RECVOPTION)
{
AfxMessageBox((LPCTSTR)PerIOData->DataBuf.buf);

PerIOData->BytesRECV = 0;

        
         Flags = 0;
         ZeroMemory(&(PerIOData->Overlapped), sizeof(OVERLAPPED));
PerIOData->Option=RECVOPTION;
         PerIOData->DataBuf.len = DATA_BUFSIZE;
         PerIOData->DataBuf.buf = PerIOData->Buffer;

         if (WSARecv(PerHandleData->Socket, &(PerIOData->DataBuf), 1, &dwBytesRecvd, &Flags,
            &(PerIOData->Overlapped), NULL) == SOCKET_ERROR)
         {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
               printf("WSARecv() failed with error %d\n", WSAGetLastError());
               return 0;
            }
         }
}

}
}
int CServerSocket::SendMsg(SOCKET cliSocket,char *buf)
{
HANDLE ComPort=CompletionPort;
DWORD dwBytesTransferred;
DWORD dwBytesSend,dwBytesRecvd;
DWORD Flags=0;
PER_IO_OPERATION_DATA* PerIOData=new PER_IO_OPERATION_DATA;
PER_HANDLE_DATA* PerHandleData=new PER_HANDLE_DATA;

         Flags = 0;

         ZeroMemory(&(PerIOData->Overlapped), sizeof(OVERLAPPED));

 strncpy(PerIOData->Buffer ,"hello world",20);
         PerIOData->DataBuf.len = DATA_BUFSIZE;
         PerIOData->DataBuf.buf = PerIOData->Buffer;
PerIOData->Option=SENDOPTION;
         if (WSASend(cSocket[0], &(PerIOData->DataBuf), 1, &dwBytesSend, Flags,
            &(PerIOData->Overlapped), NULL) == SOCKET_ERROR)
         {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
               printf("WSARecv() failed with error %d\n", WSAGetLastError());
               return 0;
            }
         }
}

#15


谢了,我改改试试

#16


基本搞定,结贴算了

#17


该回复被版主删除

#1


投递个wsaSend服务阿!

#2


我就是投的一个wsasend啊,可是不行,要是行,也就不会有这个贴子了:)

#3


如果把
DealWithMsg(...)里的
phicqmsg->SetCmd(HICQ_CMD_LOGIN);
phicqmsg->SetFlags(HICQ_FLAG_LOGIN_SUCCESS);
SendMsg(phicqmsg->GetSocket(), lpOverlappedData);
去掉,即不发消息,就没有问题。

#4


这是我一个WsaSend的处理,希望对你有用!


#define SENDOPTION 1
#define RECVOPTION 2


typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[DATA_BUFSIZE];
DWORD BytesSEND;
DWORD BytesRECV;
DWORD Option;
}PER_IO_OPERATION_DATA,*LPPER_IO_OPERATION_DATA;


int CServerSocket::SendMsg(SOCKET cliSocket,char *buf)
{
HANDLE ComPort=CompletionPort;
DWORD dwBytesTransferred;
DWORD dwBytesSend,dwBytesRecvd;
DWORD Flags=0;
PER_IO_OPERATION_DATA* PerIOData=new PER_IO_OPERATION_DATA;
PER_HANDLE_DATA* PerHandleData=new PER_HANDLE_DATA;

         Flags = 0;

         ZeroMemory(&(PerIOData->Overlapped), sizeof(OVERLAPPED));

 strncpy(PerIOData->Buffer ,"hello world",20);
         PerIOData->DataBuf.len = DATA_BUFSIZE;
         PerIOData->DataBuf.buf = PerIOData->Buffer;
PerIOData->Option=SENDOPTION;
         if (WSASend(cSocket[0], &(PerIOData->DataBuf), 1, &dwBytesSend, Flags,
            &(PerIOData->Overlapped), NULL) == SOCKET_ERROR)
         {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
               printf("WSARecv() failed with error %d\n", WSAGetLastError());
               return 0;
            }
         }
}

DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE ComPort=(HANDLE)CompletionPortID;
DWORD dwBytesTransferred;
DWORD dwBytesSend,dwBytesRecvd;
DWORD Flags=0;
LPPER_HANDLE_DATA PerHandleData;  
LPPER_IO_OPERATION_DATA PerIOData;
while(TRUE)
{
if(GetQueuedCompletionStatus(ComPort,&dwBytesTransferred,(LPDWORD)&PerHandleData,
(LPOVERLAPPED*)&PerIOData,INFINITE)==0)
{
int nErrorCode=GetLastError();
AfxMessageBox("GetQueue Failed");
return -1;
}
if(dwBytesTransferred==0)
{
closesocket(PerHandleData->Socket);
delete  PerIOData;
delete PerHandleData;
}
if(PerIOData->Option==SENDOPTION)
{
AfxMessageBox("Send SuccessFul");
continue;
}
}

#5


HunterForPig(留着口水的猪) :
很感谢你的回答,看完你的代码,似乎还是找不到答案,你能否把ServerWorkerThread里的代码贴全,或是把你整个程序发给我,谢谢!

hackangel_lili@yahoo.com.cn

#6


看看这个例子http://elssann.51.net/class.rar

#7


建议楼主看看wsasend返回值是什么。

#8


我在处理收到的消息时,又要发消息,那投下一个wsarecv是在wsasend之后还是之前啊
比如收到客户发来的消息请求得到好友列表,就要马上给他发好友列表。

#9


这个?猫王最精通

#10


stavck(关未明) :
你提供的不存在哦:)

#11


rabo(不哭死人): 你说的猫王是否为sevencat
QQ里倒是有他,但不常在线,哦,隐身了,明天请教一下:)

#12


其实关于WSASend的处理已经全了
下面那些代码是投递WSARecv请求!

#13


HunterForPig(留着口水的猪):
我发现我的程序现在可能就是wsasend & wsarecv没有投好,前几天搞好了,可我觉得有问题,改了一下,现以又有问题,我觉得以前那样不好,
能否把你的代码参考一下。

#14


#define PORT 5150
#define DATA_BUFSIZE 4096
#define SENDOPTION 1
#define RECVOPTION 2
CWinThread* pServerListenThread=NULL;
SOCKET lSocket,cSocket[64];
HANDLE CompletionPort;

DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID);
char BUF[4096];

typedef struct
{
OVERLAPPED Overlapped;
WSABUF DataBuf;
CHAR Buffer[DATA_BUFSIZE];
DWORD BytesSEND;
DWORD BytesRECV;
DWORD Option;
}PER_IO_OPERATION_DATA,*LPPER_IO_OPERATION_DATA;

typedef struct
{
SOCKET Socket;
//SOCKADDR addr;
}PER_HANDLE_DATA,*LPPER_HANDLE_DATA;

CServerSocket::CServerSocket()
{
}
int CServerSocket::StartListen(UINT& Port)
{
m_nPort=Port;

WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
AfxMessageBox("Startup Failed");
return -1;
}




lSocket=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN servAddr;
servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
servAddr.sin_port=htons(Port);

int nRet=0;
if((nRet=bind(lSocket,(SOCKADDR*)&servAddr,sizeof(servAddr)))==SOCKET_ERROR)
{
AfxMessageBox("bind socket Error");
return -1;
}

//创建一完成端口,!

CompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);

SYSTEM_INFO SystemInfo;
GetSystemInfo(&SystemInfo);

for(int i=0;i<(int)SystemInfo.dwNumberOfProcessors*2;i++)//每个comio创建两个线程
{
HANDLE ThreadHandle;
if((ThreadHandle=CreateThread(NULL,0,ServerWorkerThread,CompletionPort,0,NULL))==NULL)
{
int errorCode=GetLastError();
return -1;
}
CloseHandle(ThreadHandle);
}

if(listen(lSocket,5)==SOCKET_ERROR)
{
AfxMessageBox("listen socket Failed");
return -1;
}

pServerListenThread=AfxBeginThread(_ServerListenThread,this);


}

UINT _ServerListenThread(LPVOID lParam)
{
CServerSocket *pServ=(CServerSocket*)lParam;
SOCKET clientSocket;
SOCKADDR_IN clientAddr;
PER_HANDLE_DATA *PerHandleData=NULL;;
PER_IO_OPERATION_DATA  *PerIOData=NULL;
DWORD Flags=0;
int addrLen=sizeof(SOCKADDR_IN);

int i=0;
while(TRUE)
{
clientSocket=accept(lSocket,(SOCKADDR*)&clientAddr,&addrLen);
if(clientSocket==SOCKET_ERROR)
{
int nErrorCode=GetLastError();
AfxMessageBox("Accept failed");
return -1;
}

cSocket[i]=clientSocket;
i++;
PerHandleData=new PER_HANDLE_DATA;
PerHandleData->Socket=clientSocket;
if(CreateIoCompletionPort((HANDLE)clientSocket,CompletionPort,(DWORD)PerHandleData,0)==NULL)
{
int nErrorCode=GetLastError();
AfxMessageBox("关联句柄与端口错误");
return -1;
}


PerIOData=new PER_IO_OPERATION_DATA;
ZeroMemory(&PerIOData->Overlapped ,sizeof(OVERLAPPED));
PerIOData->Option =RECVOPTION;

PerIOData->DataBuf.buf =BUF;
//PerIOData->DataBuf.buf =PerIOData->Buffer;  
PerIOData->DataBuf.len =DATA_BUFSIZE;
PerIOData->BytesRECV=0;
PerIOData->BytesSEND=0;
Flags=0;
if(WSARecv(clientSocket,&PerIOData->DataBuf,1,&PerIOData->BytesRECV,&Flags,
&PerIOData->Overlapped,NULL)==SOCKET_ERROR)
{
if(WSAGetLastError() != WSA_IO_PENDING) 
{
int nErrorCode=GetLastError();
AfxMessageBox("第一次投递WSARecv错误");
return -1;
}
}

}
return 0;
}
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID)
{
HANDLE ComPort=(HANDLE)CompletionPortID;
DWORD dwBytesTransferred;
DWORD dwBytesSend,dwBytesRecvd;
DWORD Flags=0;
LPPER_HANDLE_DATA PerHandleData;  
LPPER_IO_OPERATION_DATA PerIOData;
while(TRUE)
{
if(GetQueuedCompletionStatus(ComPort,&dwBytesTransferred,(LPDWORD)&PerHandleData,
(LPOVERLAPPED*)&PerIOData,INFINITE)==0)
{
int nErrorCode=GetLastError();
AfxMessageBox("GetQueue Failed");
return -1;
}
if(dwBytesTransferred==0)
{
closesocket(PerHandleData->Socket);
delete  PerIOData;
delete PerHandleData;
}
if(PerIOData->Option==SENDOPTION)
{
AfxMessageBox("Send SuccessFul");
continue;
}
if(PerIOData->Option==RECVOPTION)
{
AfxMessageBox((LPCTSTR)PerIOData->DataBuf.buf);

PerIOData->BytesRECV = 0;

        
         Flags = 0;
         ZeroMemory(&(PerIOData->Overlapped), sizeof(OVERLAPPED));
PerIOData->Option=RECVOPTION;
         PerIOData->DataBuf.len = DATA_BUFSIZE;
         PerIOData->DataBuf.buf = PerIOData->Buffer;

         if (WSARecv(PerHandleData->Socket, &(PerIOData->DataBuf), 1, &dwBytesRecvd, &Flags,
            &(PerIOData->Overlapped), NULL) == SOCKET_ERROR)
         {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
               printf("WSARecv() failed with error %d\n", WSAGetLastError());
               return 0;
            }
         }
}

}
}
int CServerSocket::SendMsg(SOCKET cliSocket,char *buf)
{
HANDLE ComPort=CompletionPort;
DWORD dwBytesTransferred;
DWORD dwBytesSend,dwBytesRecvd;
DWORD Flags=0;
PER_IO_OPERATION_DATA* PerIOData=new PER_IO_OPERATION_DATA;
PER_HANDLE_DATA* PerHandleData=new PER_HANDLE_DATA;

         Flags = 0;

         ZeroMemory(&(PerIOData->Overlapped), sizeof(OVERLAPPED));

 strncpy(PerIOData->Buffer ,"hello world",20);
         PerIOData->DataBuf.len = DATA_BUFSIZE;
         PerIOData->DataBuf.buf = PerIOData->Buffer;
PerIOData->Option=SENDOPTION;
         if (WSASend(cSocket[0], &(PerIOData->DataBuf), 1, &dwBytesSend, Flags,
            &(PerIOData->Overlapped), NULL) == SOCKET_ERROR)
         {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
               printf("WSARecv() failed with error %d\n", WSAGetLastError());
               return 0;
            }
         }
}

#15


谢了,我改改试试

#16


基本搞定,结贴算了

#17


该回复被版主删除