免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2571 | 回复: 3
打印 上一主题 下一主题

一个简单的C/S TCP文件传输出问题了 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-08-13 21:14 |只看该作者 |倒序浏览
今天用测试了一下UDT, 局域网内网速能达到80Mb/sec,
然后我就写了一个简单的TCP的文件传输,,结果出问题了.
这是server端,

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <errno.h>
  5. #include <sys/socket.h>
  6. #include <arpa/inet.h>
  7. #include <netdb.h>
  8. #include <unistd.h>
  9. int main (int argc, char *argv[])
  10. {
  11.         int m_hSocket = 0;
  12.         m_hSocket = socket (AF_INET, SOCK_STREAM, 0);
  13.         struct sockaddr_in  m_nLocalAddr;
  14.         struct sockaddr_in  m_nPeerAddr;
  15.         memset (&m_nLocalAddr, 0, sizeof (struct sockaddr_in));
  16.         m_nLocalAddr.sin_family      = AF_INET;
  17.         m_nLocalAddr.sin_addr.s_addr = INADDR_ANY;//inet_addr ("192.168.51.250");//INADDR_ANY;
  18.         m_nLocalAddr.sin_port        = htons (9991);
  19.         int on = 1;
  20.         int result = setsockopt(m_hSocket, SOL_SOCKET, SO_REUSEADDR, (char *) & on, sizeof(on));
  21.         bind (m_hSocket, (struct sockaddr*)&m_nLocalAddr, sizeof(m_nLocalAddr));
  22.         listen (m_hSocket, 5);
  23.         socklen_t addrLen = sizeof (struct sockaddr);
  24.         m_hSocket = accept (m_hSocket, (struct sockaddr *)&m_nPeerAddr, &addrLen);
  25.         printf ("accept one\n");
  26.         char buff[1400];
  27.         memset (buff, 0, 1400);
  28.         int fd = open ("file", O_RDWR);
  29.         int len = 0;
  30.         while (1)
  31.         {
  32.                 printf ("start to recv data\n");
  33.                 len = read (fd, buff, 1400-4);
  34.                 if (len <= 0)
  35.                         {
  36.                         perror ("read");
  37.                         break;
  38.                         }
  39.                 //len = htonl (len);
  40.                 struct iovec iov[2];
  41.                 iov[0].iov_base = &len;
  42.                 iov[0].iov_len  = sizeof (int);
  43.                 iov[1].iov_base = buff;
  44.                 iov[1].iov_len  = len;
  45.                 int ret = writev (m_hSocket, iov, 2);
  46.                 if (ret < 0)
  47.                 {
  48.                         perror ("writev");
  49.                         break;
  50.                 }
  51.         }
  52.         return 0;
  53. }

复制代码

这是接入文件的client端

  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <errno.h>
  5. #include <sys/socket.h>
  6. #include <arpa/inet.h>
  7. #include <netdb.h>
  8. #include <unistd.h>

  9. int main (int argc, char *argv[])
  10. {
  11.     struct sockaddr_in peerAddr;
  12.     int ret = 0;
  13.     memset (&peerAddr, 0, sizeof (peerAddr));
  14.     peerAddr.sin_addr.s_addr = inet_addr (argv[1]);
  15.     printf ("ip=%s\n", argv[1]);
  16.     peerAddr.sin_family      = AF_INET;
  17.     peerAddr.sin_port        = htons (9991);
  18.     int m_hSocket = 0;
  19.     m_hSocket = socket (AF_INET, SOCK_STREAM, 0);
  20.     socklen_t addrLen = sizeof (peerAddr);
  21.     if (connect (m_hSocket, (struct sockaddr*)&peerAddr, addrLen))
  22.     {
  23.         printf ("connect failed\n");
  24.         perror ("connect");
  25.         return 0;
  26.     }

  27.     printf ("connect succ\n");
  28.     char buff[1400];
  29.     memset (buff, 0, 1400);
  30.     int fd = open ("localfile", O_CREAT | O_RDWR , 0644);
  31.     while (1)
  32.     {
  33.         int len = recv (m_hSocket, buff, 4, 0);
  34.         if (len <= 0)
  35.         {
  36.             perror ("recv");
  37.             break;
  38.         }
  39.         int datelen = 0;
  40.         memcpy (&datelen, buff, 4);
  41.         //datelen = ntohl (datelen);
  42.         printf ("date len = %d\n", datelen);
  43.         len = recv (m_hSocket, buff, datelen, 0);
  44.         if (len <= 0)
  45.         {
  46.             perror ("recv2");
  47.             break;
  48.         }
  49.         int ret = write (fd, buff, len);
  50.         if (ret <= 0)
  51.         {
  52.             perror ("write");
  53.             break;
  54.         }
  55.         memset (buff, 0, 1400);
  56.     }
  57.     close (fd);
  58.     close (m_hSocket);
  59.     return 0;
  60. }

复制代码

client 执行结果是

  1. [root@localhost app]# ./recv 192.168.51.250
  2. ip=192.168.51.250
  3. connect succ
  4. date len = 1396
  5. date len = 1396
  6. date len = 1396
  7. date len = 1835887981
复制代码

为什么后来的数据长度就变成1835887981这么大了..
server 执行结果

  1. [root@Enter-Dev-250 cui]# ./send
  2. accept one
  3. start to recv data
  4. read len = 1396
  5. start to recv data
  6. read len = 1396
  7. start to recv data
  8. read len = 1396
  9. start to recv data
  10. read len = 1396
  11. start to recv data
  12. read len = 1396
  13. start to recv data
  14. read len = 1396
  15. start to recv data
  16. read len = 1396
  17. start to recv data
  18. read len = 1396
  19. start to recv data
  20. read len = 1396
  21. start to recv data
  22. read len = 1396
  23. start to recv data
  24. read len = 1396
  25. start to recv data
  26. read len = 1396
  27. start to recv data
  28. read len = 1396
  29. start to recv data
  30. read len = 1396
  31. start to recv data
  32. read len = 1396
  33. start to recv data
  34. read len = 1396
  35. start to recv data
  36. read len = 1396
  37. start to recv data
  38. read len = 1396
  39. start to recv data
  40. read len = 1396
  41. start to recv data
  42. read len = 1396
  43. start to recv data
  44. read len = 1396
  45. start to recv data
  46. read len = 1396
  47. start to recv data
  48. read len = 1396
  49. start to recv data
  50. read len = 1396
  51. start to recv data
  52. read len = 1396
  53. start to recv data
  54. read len = 1396
  55. start to recv data
  56. read len = 1396
  57. start to recv data
  58. read len = 1396
  59. start to recv data
  60. read len = 1396
  61. start to recv data
  62. read len = 1396
  63. start to recv data
  64. read len = 1396
  65. start to recv data
  66. read len = 1396
  67. start to recv data
  68. read len = 1396
  69. start to recv data
  70. read len = 1396
  71. start to recv data
  72. read len = 1396
  73. start to recv data
  74. read len = 1396
  75. start to recv data
  76. read len = 1396
  77. writev: Connection reset by peer

复制代码

论坛徽章:
0
2 [报告]
发表于 2007-08-13 23:03 |只看该作者
len = recv (m_hSocket, buff, datelen, 0);
        if (len <= 0)
        {
            perror ("recv2");
            break;
        }

这个函数并不能按你想象的那样, 叫他读多少, 他就读多少。

在这里起码要判断len == datalen才算读完。

你最好用readn的方法来做。

论坛徽章:
0
3 [报告]
发表于 2007-08-13 23:07 |只看该作者
recv()的返回值为0并不表示出错,而是对方发送了一个EOF标志,比如在对方close()一个socket的时候.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2007-08-14 00:23 |只看该作者
呵呵..当时只是急于测试一下TCP的网络使用状况,写得也不太严谨,
听2楼的一说倒是想起来要用recvn了..
学习了..
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP