{
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);
去掉,即不发消息,就没有问题。
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;
}
}
#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
很感谢你的回答,看完你的代码,似乎还是找不到答案,你能否把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里倒是有他,但不常在线,哦,隐身了,明天请教一下:)
QQ里倒是有他,但不常在线,哦,隐身了,明天请教一下:)
#12
其实关于WSASend的处理已经全了
下面那些代码是投递WSARecv请求!
下面那些代码是投递WSARecv请求!
#13
HunterForPig(留着口水的猪):
我发现我的程序现在可能就是wsasend & wsarecv没有投好,前几天搞好了,可我觉得有问题,改了一下,现以又有问题,我觉得以前那样不好,
能否把你的代码参考一下。
我发现我的程序现在可能就是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;
}
}
}
#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);
去掉,即不发消息,就没有问题。
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;
}
}
#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
很感谢你的回答,看完你的代码,似乎还是找不到答案,你能否把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里倒是有他,但不常在线,哦,隐身了,明天请教一下:)
QQ里倒是有他,但不常在线,哦,隐身了,明天请教一下:)
#12
其实关于WSASend的处理已经全了
下面那些代码是投递WSARecv请求!
下面那些代码是投递WSARecv请求!
#13
HunterForPig(留着口水的猪):
我发现我的程序现在可能就是wsasend & wsarecv没有投好,前几天搞好了,可我觉得有问题,改了一下,现以又有问题,我觉得以前那样不好,
能否把你的代码参考一下。
我发现我的程序现在可能就是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;
}
}
}
#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
基本搞定,结贴算了