Socket的udp上传recvfrom单独取一个线程的问题?

Eddydada 2011-12-29 07:14:04
各位大虾们,最近在写socket的udp的上传程序。现在遇到一个问题。
当使用sendto和recvfrom在同一个线程中时,程序完全没有问题。这样必须倒带数据发完了才能接收数据。到数据比较大时,程序就收不到服务器的应答包了(我上传数据的时候只要超过了17k就收不全数据了)。我想可能是没有及时对服务器的应答包做及时的处理导致丢包了。
现在我把sendto 和recvfrom写在两个线程里面,程序一运行就启动recvfrom函数。但是现在就收不到服务器的应答数据包了。我已经使用了bind了。附上部分代码:

recvfrom:
struct sockaddr_in add2;
int iLen2 =sizeof(add2);
// ZeroMemory(&add2,iLen2);
add2.sin_family=AF_INET;
add2.sin_port=htons(8080);
add2.sin_addr.s_addr = inet_addr("127.0.0.1");

struct sockaddr_in add;
int iLen =sizeof(add);
add.sin_family=AF_INET;
add.sin_port=htons(60000); ///server的监听端口
add.sin_addr.s_addr = inet_addr("222.35.136.224");

SOCKET hSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (hSocket == INVALID_SOCKET)
{
AfxMessageBox(_T("socked failed"));
WSACleanup();
return 0;
}

if(bind(hSocket, (struct sockaddr*)&add2, iLen2))
{
CString str;
str.Format(_T("recieve error: %d\n"), WSAGetLastError());
AfxMessageBox(str);
return 0;
}

char recvBuf[1024] = {0};
int dwRecv = 0;
while(1)
{
dwRecv = recvfrom(hSocket, recvBuf , 1024, 0, (struct sockaddr*)&add, &iLen);
if(dwRecv == SOCKET_ERROR)
{
CString str;
str.Format(_T("recieve error: %d\n"), WSAGetLastError());
AfxMessageBox(str);
break;
return 0;
}

sendto:
struct sockaddr_in add;
int iLen =sizeof(add);
ZeroMemory(&add,iLen);
add.sin_family=AF_INET;
add.sin_port=htons(60000); ///server的监听端口
add.sin_addr.s_addr = inet_addr("222.35.136.224");

SOCKET hSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (hSocket == INVALID_SOCKET)
{
AfxMessageBox(_T("socked failed"));
WSACleanup();
dlg->m_bSuccess =0;
dlg->UpdateList();
return dlg->m_bSuccess;
}

DWORD dwSend2=0,dwTemp2=0;
char* fBuf = fileBuff;
DWORD fSize = dlg->m_dwFileSize;
DWORD dTemp = 0;
// int iPack = 0;
while(fSize)
{
dwSend2 = sendto(hSocket, fBuf+dwTemp2, min(fSize,1000), 0, (struct sockaddr*)&add, iLen); //send
printf("send data to server:-----start-----\r\n%s\r\n------end------\r\n", fBuf+dwTemp2);
if(dwSend2 == SOCKET_ERROR)
{
CString str;
str.Format(_T("Error on send file %d\n"), WSAGetLastError());
AfxMessageBox(str);
dlg->m_bSuccess =0;
dlg->UpdateList();
return dlg->m_bSuccess;
}


麻烦各位大大们,看看是什么问题。服务器那边应该是没有问题的,因为已经可以收数据了。
请各位大大多多指点啊。。。。
...全文
195 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Eddydada 2012-02-07
  • 打赏
  • 举报
回复
自己解决了,结贴吧。给大家说下自己的心得。
首先,先启动recvfrom函数时,必须先bind端口,否则会出错。然后调用sendto时,要bind和recvfrom的同一个端口,不然就收不到数据。接下来重用一个端口就可以了,用setsockopt搞定。
o544784874 2012-01-06
  • 打赏
  • 举报
回复
你每使用一次SENDTO发送的数据是有限的,网络的MTU只有1498字节(没记错的话),所以你每SENDTO一次就必须等RECVFROM有回应之后才能SENDTO第二次,你自己应该有个应答机制,否则你传的数据始终是有问题的,虽然数据可以传输。数据量一大肯定就出问题了
fishion 2012-01-06
  • 打赏
  • 举报
回复
改用select模型吧
shn521 2012-01-05
  • 打赏
  • 举报
回复
发送端循环里Sleep一会呢
hao48080412 2012-01-05
  • 打赏
  • 举报
回复
线程同步。
Eddydada 2011-12-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 quwei197874 的回复:]
加上事件同步,否则线程执行的顺序是不定的
[/Quote]
不大明白你的意思。我是程序初始化的时候就启动接受函数。一直等待数据的到来,难道设计有错吗。

请大大们指点下。。。
quwei197874 2011-12-30
  • 打赏
  • 举报
回复
加上事件同步,否则线程执行的顺序是不定的
Eddydada 2011-12-30
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 visualeleven 的回复:]
先用抓包工具看看有数据包到达客户端没?
[/Quote]
感谢斑竹的回复。我这个是在wince设备上的,而且必须用的是gprs连的网络。否则服务器那边根本发不到数据到我这里。 这么办啊。。
Eddydada 2011-12-30
  • 打赏
  • 举报
回复
大大们怎么都不来呢?
这个问题都难倒了CSDN的大虾们吗?不可能啊,都帮忙指点指点啊。。。
Eleven 2011-12-29
  • 打赏
  • 举报
回复
先用抓包工具看看有数据包到达客户端没?
Eddydada 2011-12-29
  • 打赏
  • 举报
回复
csdn的大大们,牛牛们,帮忙看看啊。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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