socket通信问题,请大家进来看看!

jianzhibeihang 2009-10-08 10:45:42
程序的功能就是建立一个socket,客户端和服务器端进行通信,客户端发送一个消息到服务器,服务器返回一个应答,然后客户端创建一个新的线程接收出来服务器返回的数据。问题就在如果在客户端不用bind()函数就收不到服务器返回的数据?不知道这个问题该怎么解决!!! 请大牛指导啊


#include "stdafx.h"
#include "UDPSession.h"
#include <windows.h>
#include <mmsystem.h>
//#include "time.h"
///////////////////////////////////
//
//////////////////////////////////
UDPSession::UDPSession()
{
sendtime = 0;
arrivetime = 0;
}

UDPSession::~UDPSession()
{
}
/////////////////////////////////////////
//function:
//////////////////////////////////////////

int UDPSession::InitialUDPSession()
{
WSADATA wsaData;
if(NO_ERROR != WSAStartup(MAKEWORD(2, 2), &wsaData))
{
return -1;
}
#if defined SERVER
sockSrv = socket(AF_INET, SOCK_DGRAM, 0);
localAddr.sin_family = AF_INET;
localAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(5001);

if(SOCKET_ERROR == bind(sockSrv, (sockaddr *)&localAddr, sizeof(sockaddr)))
{
closesocket(sockSrv);
WSACleanup();
return -1;
}

rcv_thread = CreateThread(NULL, 0, ServerReceiveThread, this, 0, NULL);
if(NULL == rcv_thread)
{
closesocket(sockSrv);
WSACleanup();
return -2;
}
#elif defined CLIENT
sockCln = socket(AF_INET, SOCK_DGRAM, 0);

localAddr.sin_family = AF_INET;
localAddr.sin_port = htons(5001);
localAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

bind(sockCln, (sockaddr *)&localAddr, sizeof(sockaddr));

remoteAddr.sin_family = AF_INET;
remoteAddr.sin_port = htons(5001);
remoteAddr.sin_addr.S_un.S_addr = inet_addr("144.214.37.244");


rcv_thread = CreateThread(NULL, 0, ClientReceiveThread, this, 0, NULL);
if(NULL == rcv_thread)
{
closesocket(sockCln);
WSACleanup();
return -2;
}
CreateFile();

#endif
return 0;
}
/////////////////////////////////////////////////
//
/////////////////////////////////////////////////

DWORD UDPSession::ServerReceiveThread(LPVOID lpParameter)
{
unsigned int arrivetime;
UDPSession *p = (UDPSession *)lpParameter;
p->fromlen = sizeof(sockaddr);
while(1)
{
recvfrom(p->sockSrv, p->buffer, sizeof(int)*2, 0, (sockaddr *)&(p->remoteAddr), &(p->fromlen));
arrivetime = timeGetTime();
*(unsigned int *)(p->buffer + 4) = arrivetime;
sendto(p->sockSrv, p->buffer, sizeof(int)*2, 0, (sockaddr *)&(p->remoteAddr),p->fromlen);
}
return 1;
}
///////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////
DWORD UDPSession::ClientReceiveThread(LPVOID lpParameter)
{
UDPSession *p = (UDPSession *)lpParameter;
p->fromlen = sizeof(sockaddr);
while(1)
{
recvfrom(p->sockCln, p->buffer, sizeof(int)*2, 0, (sockaddr *)&(p->remoteAddr),&(p->fromlen));
p->arrivetime = timeGetTime();
p->ReceivePacket(p->buffer, p->arrivetime);
}
return 1;
}

void UDPSession::ReceivePacket(char *p, unsigned int t)
{
RTTLog<<*(unsigned int *)p<<' '<<*(unsigned int *)(p + 4)<<' '<<t<<endl;
}

int UDPSession::SessionShutDown()
{
TerminateThread(rcv_thread, 0);
#if defined SERVER
closesocket(sockSrv);
#elif defined CLIENT
closesocket(sockCln);
CloseFile();
#endif
WSACleanup();
return 1;
}
/////////////////////////////////////////
//
/////////////////////////////////////////

void UDPSession::SendRTTPacket()
{
char sendbuf[8];
sendtime = timeGetTime();
*(unsigned int *)(sendbuf) = sendtime;
sendto(sockCln, sendbuf, sizeof(int)*2, 0, (const sockaddr *)&remoteAddr,sizeof(sockaddr));
}
////////////////////////////////////
//
///////////////////////////////////
void UDPSession::CreateFile()
{
RTTLog.open("RTTClient.txt");
}
//////////////////////////////////
//
//////////////////////////////////
void UDPSession::CloseFile()
{
RTTLog.close();
}
...全文
105 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
野男孩 2009-10-09
  • 打赏
  • 举报
回复
你不bind的话,怎么能收到数据啊!!!在哪个端口收?还不是靠bind指定的。
xylicon 2009-10-08
  • 打赏
  • 举报
回复
你是用无连接的传输方式,接收端(包括你所说的客户端,只要你用recvfrom接收数据都是接收端)用bind绑定接口来接收数据这是很正常的。
jianzhibeihang 2009-10-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 oyster2008 的回复:]
主要是你的ServerReceiveThread有点小问题:
发送数据到客户端的时候,使用了:
sendto(p->sockSrv, p->buffer, sizeof(int)*2, 0, (sockaddr *)&(p->remoteAddr),p->fromlen);
而你的remoteAddr实际上是一个固定的套接字地址,端口号是5001,所以如果client不绑定到5001端口它就收不到服务器的数据,你应该将sendto改成客户端发送数据时使用的地址,而不是使用固定的remoteAddr
[/Quote]

不是的
那是绑定后才有的固定的5001端口
没有绑定的时候没有固定的端口

remoteAddr是客户端发送数据时候的端口

绑定后
客户端发送和接受都是用的5001
jianzhibeihang 2009-10-08
  • 打赏
  • 举报
回复
这么晚大家还在看帖啊 感动啊!!!
FJDHT444 2009-10-08
  • 打赏
  • 举报
回复
顶一个
illuminati 2009-10-08
  • 打赏
  • 举报
回复
因为你用的是是UDP编程。
看你开几条通道了,根据需要自己定。
如果只开一条,只要服务器bind就行了,客户端连接上后,互相都可以收发数据的。
如果要开两条通道,则收发方各bind一个端口进行监听,等待对方连接,建立连接后两条通道都可以收发数据,不过你可以规定a-->b用通道1,b-->a用通道2。
oyster2008 2009-10-08
  • 打赏
  • 举报
回复
主要是你的ServerReceiveThread有点小问题:
发送数据到客户端的时候,使用了:
sendto(p->sockSrv, p->buffer, sizeof(int)*2, 0, (sockaddr *)&(p->remoteAddr),p->fromlen);
而你的remoteAddr实际上是一个固定的套接字地址,端口号是5001,所以如果client不绑定到5001端口它就收不到服务器的数据,你应该将sendto改成客户端发送数据时使用的地址,而不是使用固定的remoteAddr

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧