免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 如戏
打印 上一主题 下一主题

请教关于socket发送大量数据的问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2010-03-14 00:07 |只看该作者
按你的描述应该是不会那样的问题的, 程序应该不少, 把关键点代码贴上来吧.

论坛徽章:
0
12 [报告]
发表于 2010-03-14 11:04 |只看该作者
  1. int g_isendpackage = 10*1024;

  2. DWORD WINAPI recvthread(void *param)
  3. {
  4.         SOCKET sock = (SOCKET)param;
  5.         char buf[1024];
  6.         while(true)
  7.         {
  8.                 int iRet = recv(sock, buf, sizeof(buf), 0);
  9.                 if (iRet <= 0)
  10.                 {
  11.                         printf("接收失败 %d %d\n", iRet, WSAGetLastError());
  12.                         break;
  13.                 }
  14.                 else
  15.                 {
  16.                         printf("接收 %d\n", iRet);
  17.                 }
  18.         }
  19.         return 0;
  20. }

  21. DWORD WINAPI sendthread(void *param)
  22. {
  23.         SOCKET sock = (SOCKET)param;
  24.         char *pdata = new char[g_isendpackage];
  25.         while(true)
  26.         {
  27.                 int iRet = send(sock, pdata, g_isendpackage, 0);
  28.                 if (iRet <= 0)
  29.                 {
  30.                         printf("发送失败 %d %d\n", iRet, WSAGetLastError());
  31.                         break;
  32.                 }
  33.                 else
  34.                 {
  35.                         printf("发送 %d\n", iRet);
  36.                 }
  37.         }
  38.         delete []pdata;
  39.         return 0;
  40. }
复制代码
这是个测试例子, 没有任何业务.
我还发现, 如果服务端每次发64K不会断, 每次发10K竟然会断. 完全相不明白, 是不是和网通与电信的网关设置有关系?

论坛徽章:
0
13 [报告]
发表于 2010-03-14 11:07 |只看该作者

  1. #include <stdio.h>
  2. #include <winsock.h>
  3. #pragma comment(lib, "ws2_32.lib")

  4. int main(int argc, char *argv[])
  5. {
  6.         WSADATA wsaData;
  7.         if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 )
  8.         {
  9.                 printf("init error: %d\n",WSAGetLastError());
  10.                 return -1;
  11.         }

  12.         int iPort = 8002;
  13.         if (argc > 1)
  14.         {
  15.                 iPort = atoi(argv[1]);
  16.         }
  17.         if (argc > 2)
  18.         {
  19.                 g_isendpackage = atoi(argv[2]);
  20.         }

  21.         printf("port %d len %d\n", iPort, g_isendpackage);

  22.         SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  23.         sockaddr_in service;
  24.         service.sin_family = AF_INET;
  25.         service.sin_addr.s_addr = 0;
  26.         service.sin_port = htons(iPort);

  27.         if (bind(sock, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR)
  28.         {
  29.                 printf("bind() failed. %d\n", WSAGetLastError());
  30.                 closesocket(sock);
  31.                 return -1;
  32.         }

  33.         if (listen(sock, 5) == SOCKET_ERROR)
  34.         {
  35.                 printf("listen failed %d\n", WSAGetLastError());
  36.                 return -1;
  37.         }
  38.         printf("listen success\n");
  39.         while(true)
  40.         {
  41.                 SOCKET accsock = accept(sock, NULL, NULL);
  42.                 if (accsock == SOCKET_ERROR)
  43.                 {
  44.                         continue;
  45.                 }

  46.                 HANDLE hrecv = CreateThread(NULL, 0, recvthread, (void*)accsock, 0, NULL);
  47.                 CloseHandle(hrecv);
  48.                 HANDLE hsend = CreateThread(NULL, 0, sendthread, (void*)accsock, 0, NULL);
  49.                 CloseHandle(hsend);
  50.         }

  51.         WSACleanup();
  52.         return 0;
  53. }
复制代码
VC++2005编译的

论坛徽章:
0
14 [报告]
发表于 2010-03-14 11:09 |只看该作者
本帖最后由 如戏 于 2010-03-14 11:33 编辑

我的电信的ADSL, 连电信的服务器又没问题.
一次send发64K正常, 发10K出错
我想应该是防火墙的原因, 因为发10发得快. 发64K发得慢.
也许被认为是出站攻击吧

论坛徽章:
0
15 [报告]
发表于 2010-03-14 14:21 |只看该作者
send(sock, pdata, g_isendpackage, 0);
recv(sock, buf, sizeof(buf), 0);

看下这两个函数的具体参数长度的意思。
LZ你换成这样 前成四个字节表示数据长度,后面是内容,接收和发送都按实际的buf发送和接收就不会有问题了,特别对于阻塞这种操作。send和recv要判断返回值,send一次要把buf数据全发送出去,recv一次要接收完前四个字节定义的长度值。

你这种发送,接收不会有问题的,问题在上面说的这个原因。

论坛徽章:
0
16 [报告]
发表于 2010-03-14 14:40 |只看该作者
还以为你在单机测试呢, 原来还跨电信网通. 你先在单机或者内网中的两台机器测试下, 如果没问题, 估计是网络的问题了.

论坛徽章:
0
17 [报告]
发表于 2010-03-14 17:22 |只看该作者
回复 16# ideawu


    同是电信的网络就没有问题

论坛徽章:
0
18 [报告]
发表于 2010-03-14 17:25 |只看该作者
本帖最后由 如戏 于 2010-03-14 17:26 编辑

回复 15# 独臂剑客


  我这个只是测试网络, 要不要协议头部都没有关系吧?
我发送和接收的数据都没有一点意义, 纯粹是测试网络.

论坛徽章:
0
19 [报告]
发表于 2010-03-14 20:16 |只看该作者
回复 18# 如戏


    给你说个简单的例子吧
   
   int send( SOCKET s,      const char FAR *buf,      int len,      int flags );  
    你的buf发送长度是10K 这个时候只发送了8K, 里面还有2K
   
    你下次再发10K数据,其实buf里有12K数据,你下次最多一次只发送10K,再第三次发送的时候里面其实只有2K数据,send不会返回的
   其它的不多说了。

论坛徽章:
0
20 [报告]
发表于 2010-03-14 21:15 |只看该作者
断开链接是什么意思,是你的程序执行返回了,还是socket自动断开?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP