winsock UDP 点对点接收消息问题(特急)

metyph 2007-01-29 12:36:57
建立一个socket后向服务器发送消息(循环发送)~但服务器只能接收一条消息(其它机子发时也只能收到一条消息)~其它消息接收不到~发送消息有时间间隔::Sleep(100);客户端也只能偶尔收到一条来自服务器的回应消息。
为什么??我百思不得其解~~如今~~~求求求求解!!!!!!!!!!!!
...全文
417 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
metyph 2007-02-05
  • 打赏
  • 举报
回复
解决了~~设置为非堵塞就行了~
metyph 2007-01-31
  • 打赏
  • 举报
回复
TO pp616(坏蛋)

不行啊!! T_T
pp616 2007-01-31
  • 打赏
  • 举报
回复
在进入循环前试试
int tout=3000;
::setsockopt(ServerSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&tout,sizeof(tout));

或着用select来代替阻塞。
metyph 2007-01-30
  • 打赏
  • 举报
回复
过了一天了~怎么都没人了的??
metyph 2007-01-30
  • 打赏
  • 举报
回复
用Ethereal有包发出~服务器也有包发回来~~可是客户端这边就是没有反应~
为什么啊??????????
metyph 2007-01-30
  • 打赏
  • 举报
回复
谢谢huzhangyou(信仰(http://www.libing.net.cn))的回复~我会到你的BLOG看看的~

谢谢 pp616(坏蛋) 指出我的错误~现在已经改了~之前也是没用free的~我知道这样也不对~但怎么都接收不了消息~只要一启动接收消息线程被堵住(这个线程就一个while循环)~发不出消息~也收不到消息~

能有什么方法吗?给点思路也好~已经两天了 T_T
pp616 2007-01-30
  • 打赏
  • 举报
回复
楼主还是先看看C++本身的东西吧。
pp616 2007-01-30
  • 打赏
  • 举报
回复
//回发(KEEP)类型的消息
stSERVERTOCLIENTMSG Msg;
Msg.iMsgType = MESSAGEBACK;//
strcpy(Msg.Message.loginmessage.username,RecvMsg.Message.loginmessage.username);
sendto(ServerSocket, (const char*)&Msg, sizeof(Msg), 0,(const sockaddr*)&sender, sizeof(sender));
free(&Msg);
}
free(&msg)错!!

free(&RecvMsg); 错!!
free(&sender); 错!!
wood542344 2007-01-30
  • 打赏
  • 举报
回复
现在怎么最喜欢用自己写的东西啊。VCL不是有包好的吗?
huzhangyou 2007-01-30
  • 打赏
  • 举报
回复
还有一点 使用ethereal检测一下 发包情况
huzhangyou 2007-01-30
  • 打赏
  • 举报
回复
这样看代码太困难了

很多时候 你可以考虑使用INdy

毕竟人家封装的还是很好的

更大一点的架构可以考虑ACE

我的博客是专门做服务器设计的

或许对你有帮助

http://www.libing.net.cn/index.php
metyph 2007-01-30
  • 打赏
  • 举报
回复
似乎是接收被堵塞了什么的~可不知道怎么解决~~
metyph 2007-01-30
  • 打赏
  • 举报
回复
不得啊~现在的问题是:如果只发不收的话就正常~但如果启动了接收线程~就会偶尔能发出~也偶尔能接收~但大部分还是发不出接不到~
UDP的风络编程我也刚接触不是很久~~但由于工程问题要我尽快完成~~
各位大虾~有什么好的方法吗?赐教一下吧~~ T_T
TheGenius 2007-01-30
  • 打赏
  • 举报
回复
不过现在还要看你怎么做那个用户对用户的通信了.
TheGenius 2007-01-30
  • 打赏
  • 举报
回复
汗,不是可以用了吗,你还不如把分给我得了........1311
metyph 2007-01-29
  • 打赏
  • 举报
回复
服务器端(这里都是在线程里的):

//---------------------------初始化Socket---------------------------------------
int __fastcall TGxtServerSocket::InitWinSocket()
{
WORD version = MAKEWORD(2,0);
if ( ::WSAStartup(version,&WSAData) != 0)
{
return 0;
}
else
{
return 1;
}
}
//----------------------------新建Socket----------------------------------------
int __fastcall TGxtServerSocket::CreateSocket(int socktype)
{
ServerSocket = socket(AF_INET,socktype,0);
if ( ServerSocket == NULL )
{
return 0;
}
else
{
return 1;
}
}
//---------------------------挷定Socket-----------------------------------------
int __fastcall TGxtServerSocket::BindSocket()
{
if (VarPort!="")
{
ServerPort = StrToInt(VarPort);//更改端口号
}

local.sin_family = AF_INET;
local.sin_port = htons(ServerPort);
local.sin_addr.S_un.S_addr = INADDR_ANY;

if ( bind(ServerSocket,(sockaddr*)&local,sizeof(sockaddr)) == SOCKET_ERROR )
{
return 0;
}
else
{
return 1;
}

}
//----------------------------------关闭Socket----------------------------------
bool __fastcall TGxtServerSocket::CloseSocket()
{
//
bool reValue = false;
try
{
closesocket(ServerSocket);// = NULL;
ServerSocket = NULL;
WSACleanup();
reValue = true;
}
catch(Exception &E)
{
//
}
return reValue;
}
//------------------------------------------------------------------------------
void __fastcall TGxtServerSocket::Execute()
{
//-------------------初始化Socket---------------------------------------
if ( InitWinSocket() == 0 )
{
this->Terminate();
}
if ( CreateSocket(SOCK_DGRAM) == 0 )
{
this->Terminate();
}
if ( BindSocket() == 0 )
{
this->Terminate();
}
try
{

while(!Terminated)
{
sockaddr_in sender;
stSERVERTOCLIENTMSG RecvMsg;
memset(&RecvMsg,0,sizeof(stSERVERTOCLIENTMSG));
int dwSender = sizeof(sender);
int ret = recvfrom(ServerSocket, (char *)&RecvMsg,sizeof(stSERVERTOCLIENTMSG), 0, (sockaddr *)&sender,&dwSender);
if(ret <= 0)
{

continue;
}
//判断消息的类型
switch(RecvMsg.iMsgType)
{
//登陆请求
case LOGIN :
{

//回发(KEEP)类型的消息
stSERVERTOCLIENTMSG Msg;
Msg.iMsgType = MESSAGEBACK;//
strcpy(Msg.Message.loginmessage.username,RecvMsg.Message.loginmessage.username);
sendto(ServerSocket, (const char*)&Msg, sizeof(Msg), 0,(const sockaddr*)&sender, sizeof(sender));
free(&Msg);
}
//退出请求
case LOGOUT :
{
...
}
}
free(&RecvMsg);
free(&sender);
}
}
catch(Exception &E)
{
//
}
}
各位大哥大姐~~帮帮忙啊~~
pp616 2007-01-29
  • 打赏
  • 举报
回复
没看出什么问题。服务器那边的呢。
metyph 2007-01-29
  • 打赏
  • 举报
回复
大致代码如下:
如还不清楚的~我还会继续把代码贴出来~~~

struct stLOGINMSG
{
char username[20];
char password[20];
};
struct stSERVERTOCLIENTMSG
{
int iMsgType;//自定义的消息类型
union _message
{
stLOGINMSG loginmessage; //登陆
stLOGOUTMSG logoutmessage; //注销
stUSERLISTNODE userlist; //用户列表
}Message;
};
//下面用到的SockSrvIP,ServerPort都是全局,定义好了的
void __fastcall TThreadLogin::Execute()
{

char szTmp[256],buf[2096];
unsigned long nAddr = inet_addr(SockSrvIP.Trim().c_str());//服务器IP
if ( nAddr == INADDR_NONE)
{
DealException("无效的IP地址","错误",MB_OK+MB_ICONERROR,true);
return;
}

::ZeroMemory(&GxtMain->wsaData,sizeof(WSAData));
WORD version = MAKEWORD(2,0);

if ( ::WSAStartup(version,&GxtMain->wsaData) !=0 )
{
DealException("Failed to initial winsock enviroment!","Gxt Error",MB_OK+MB_ICONERROR,true);
return;
}

char ComputerName[255];

gethostname(ComputerName,255);//得本计算机名

struct hostent *he = gethostbyname(ComputerName);
if ( !he )
{
DealException("Failed to get information to host!","Gxt Error",MB_OK+MB_ICONERROR,true);
::WSACleanup();
return;
}
//建立一个新的Socket
GxtMain->Socket = INVALID_SOCKET;
//UDP方式
GxtMain->Socket = socket(AF_INET,SOCK_DGRAM,0);

if ( GxtMain->Socket == INVALID_SOCKET)
{
DealException("Failed to create a new socket!","Gxt Error",MB_OK+MB_ICONERROR,true);
::WSACleanup();
return;
}

struct sockaddr_in client;
unsigned long nClient;
memcpy(&nClient,he->h_addr_list[0],sizeof(int));

if ( nClient == INADDR_NONE)
{
DealException("无法获取客户端IP地址","Gxt Error",MB_OK+MB_ICONERROR,true);
closesocket(GxtMain->Socket);
::WSACleanup();
return;
}

client.sin_family = AF_INET;
client.sin_port = 0;
client.sin_addr.S_un.S_addr = (int)nClient;// INADDR_ANY;

if ( ::bind(GxtMain->Socket,(struct sockaddr*)&client,sizeof(struct sockaddr)) == SOCKET_ERROR)
{
DealException("Failed to bind socket!","Gxt Error",MB_OK+MB_ICONERROR,true);
::WSACleanup();
closesocket(GxtMain->Socket);
return;
}
sockaddr_in remote;
remote.sin_addr.S_un.S_addr = inet_addr(SockSrvIP.c_str());
remote.sin_family = AF_INET;
remote.sin_port = htons(SockSrvPort);

stSERVERTOCLIENTMSG sendbuf;
sendbuf.iMsgType = LOGIN; //KEEP
strncpy(sendbuf.Message.loginmessage.username, GxtMain->edtUserName->Text.Trim().c_str(), 20);
int sReturn;
sReturn = sendto(GxtMain->Socket, (const char*)&sendbuf, sizeof(sendbuf), 0, (const sockaddr*)&remote,sizeof(remote)+1);

while(!Terminated)
{
::Sleep(500);
int iread;
sockaddr_in remote;
int sinlen = sizeof(remote);
stSERVERTOCLIENTMSG Msg;
sinlen = sizeof(struct sockaddr_in);
iread = ::recvfrom(GxtMain->Socket, (char *)&Msg, sizeof(Msg), 0, (sockaddr *)&remote, &sinlen);
if (iread < 0 )
{
ViewLogMsg = "iread<0";
Synchronize(LogMsg);
continue;
}
try
{
ViewLogMsg = "收到消息:"+ IntToStr(Msg.iMsgType)+ "Server Port:" + IntToStr(ntohs(remote.sin_port))+ "MSG:" + (AnsiString)Msg.Message.userlist.username;
Synchronize(LogMsg);
}
catch(Exception &E)
{
ViewLogMsg = "error:"+E.Message;
Synchronize(LogMsg);
}
::Sleep(100);
sockaddr_in re;
re.sin_addr.S_un.S_addr = inet_addr(SockSrvIP.c_str());
re.sin_family = AF_INET;
re.sin_port = htons(SockSrvPort);

stSERVERTOCLIENTMSG sendbuf;
sendbuf.iMsgType = KEEP; //LOGIN
strncpy(sendbuf.Message.loginmessage.username, GxtMain->edtUserName->Text.Trim().c_str(), 20);
sendto(GxtMain->Socket, (const char*)&sendbuf, sizeof(sendbuf), 0, (const sockaddr*)&re,sizeof(re)+1);
::Sleep(100);
}
}
pp616 2007-01-29
  • 打赏
  • 举报
回复
代码贴出来。
metyph 2007-01-29
  • 打赏
  • 举报
回复
help me !!!!!!!!!!!

1,316

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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