我试图在异步模式下使用winsock2。我能够从客户端向服务器发送消息,但不能从服务器发送到客户端。当我在客户端调用recv时,缓冲区中没有收到任何内容。
这是我的客户代码
ClientSocket::ClientSocket (HWND& pHwnd)
{
WSADATA wsdata;
vSzIncoming = 0;
int error = WSAStartup (MAKEWORD(2,2), &wsdata);
vSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
error = WSAAsyncSelect (vSocket, pHwnd, WM_SOCKET, (FD_CLOSE | FD_READ));
vHwnd = pHwnd;
vIsConnected = false;
}
bool ClientSocket::ConnectToServer ()
{
SockAddr.sin_port = htons (20000);
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = inet_addr ("127.0.0.1");
if(connect (vSocket, (LPSOCKADDR)(&SockAddr), sizeof (SockAddr)) == SOCKET_ERROR) {
vIsConnected = false;
return false;
}
vIsConnected = true;
return true;
}
void ClientSocket::SendMsg (const MessageGenerator& pMessageGenerator)
{
send(vSocket, pMessageGenerator.GetMessage ().Buffer (), pMessageGenerator.GetLength (), 0);
}
char * ClientSocket::ReceiveMsg ()
{
char temp[1024];
ZeroMemory (temp, sizeof (temp));
int inDataLength = recv (vSocket,
(char*)temp,
sizeof (temp) / sizeof (temp [0]),
0);
return temp;
}
这是服务器代码
WSADATA WsaDat;
int nResult=WSAStartup(MAKEWORD(2,2),&WsaDat);
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
SOCKADDR_IN SockAddr;
SockAddr.sin_port=htons(nPort);
SockAddr.sin_family=AF_INET;
SockAddr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(Socket,(LPSOCKADDR)&SockAddr,sizeof(SockAddr))==SOCKET_ERROR)
{
}
nResult=WSAAsyncSelect(Socket,
hWnd,
WM_SOCKET,
(FD_CLOSE|FD_ACCEPT|FD_READ));
if(listen(Socket,(1))==SOCKET_ERROR)
{
}
//发送部分
String str ="1;yahoo;|";
send(Socket,str.Buffer(),str.GetLength(),0);
//接收部分
case WM_SOCKET:
{
switch(WSAGETSELECTEVENT(lParam))
{
case FD_READ:
{
char szIncoming[1024];
ZeroMemory(szIncoming,sizeof(szIncoming));
int inDataLength=recv(Socket,
(char*)szIncoming,
sizeof(szIncoming)/sizeof(szIncoming[0]),
0);
String str(szIncoming);
wcsncat(szHistory,str.GetTChar(),inDataLength);
wcscat(szHistory,L"\r\n");
SendMessage(hEditIn,
WM_SETTEXT,
sizeof(szIncoming)-1,
reinterpret_cast<LPARAM>(&szHistory));
}
case FD_ACCEPT:
{
int size=sizeof(sockaddr);
Socket=accept(wParam,&sockAddrClient,&size);
}
请帮帮我
答案 0 :(得分:1)
很难说出你的问题所在。最好的解决方案是系统地删除所有可能的障碍:
recv
的返回值。如果出现错误,则缓冲区不受影响,因此返回“空”字符串。还有一个很大的错误,你应该立即纠正你的代码:
char * ClientSocket::ReceiveMsg ()
{
char temp[1024];
ZeroMemory (temp, sizeof (temp));
int inDataLength = recv (vSocket,
(char*)temp,
sizeof (temp) / sizeof (temp [0]),
0);
return temp; // ** don't return a local memory "object" **
}
不要那样做。使用_strdup返回副本或使用并返回“String”对象。当然,如果你使用_strdup
,调用者必须使用适当的函数(free
)释放内存。啊,是的,第三种可能性就是期望缓冲区作为参数给出,就像recv一样。