免费注册 查看新帖 |

Chinaunix

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

关于TCP有序传输的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-02-17 18:23 |只看该作者 |倒序浏览
假设有2个字符串A,B,通过2次send发送出去,在接收端用recv接收。假设recv一次不能完全接受A字符串的全部内容,可能为N次,那么我想问一下,在第一次调用recv接收到部分A字符串,第二次调用recv接受的内容肯定是A字符串的么?会不会是B字符串的内容?请大家指教。

这个问题我还搞不清楚,看书上说,TCP协议可以保证数据的有序传输,也就是说我使用send发送内容,recv肯定能完整无错的收到。但是我使用了nonblock的recv,recv会马上返回,不管接收到多少数据,也就是说可能只收到部分的内容,就返回了,我还要自己判断,继续调用recv,直到全部接收。不知道以上我的理解时候正确,请大家指正其中的错误,谢谢:)

论坛徽章:
0
2 [报告]
发表于 2003-02-17 19:21 |只看该作者

关于TCP有序传输的问题

不一定
就是说你send了几次
并不是一定会recv几次
可能一次收到所有

也可能用更多次数收才能收完

这种问题一般在发送前先发送一个长度字符表示自己想发送的内容的长度

然后再发内容

接收时先接收长度
再根据长度接收指定长度的内容


一般可以用一个short表示自己想发的长度

论坛徽章:
0
3 [报告]
发表于 2003-02-17 20:57 |只看该作者

关于TCP有序传输的问题

对,我就是这么做的,在消息头用一个short定义长度,最坏的可能就是一次只收到1个字节,那么就不知道这条消息的具体长度了。撇开这个不说。

接受消息,在internet上,一次收到所有的消息倒不是大问题,最大的问题就在于一次发送,多次接受。我想斑竹可能没完全理解我第一个问题,我的问题是:

字符串A AAAAAAAAAA
字符串B BBBBBBBBBB

然后使用send,先后发送字符串A和B。

接收端第一次使用recv,收到内容AAAAA,那么请问,第二次使用recv,会不会收到B打头的内容,是不是要等到收到全部的A只有,才会收到B打头的内容?

我搞不清楚,谢谢:)

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2003-02-17 23:26 |只看该作者

关于TCP有序传输的问题

就是,TCP 绝对保证有序。如果是先发送 A,再发送 B 的话,那么肯定是先收到 A,再收到 B ---- 尽管 A 不一定一次收到。

论坛徽章:
0
5 [报告]
发表于 2003-02-18 00:28 |只看该作者

关于TCP有序传输的问题

谢谢,刚才在路上我也在琢磨。一旦建立了通道,就好像两条单车道的路,同向行驶,先出发的一般先到,后出发的后到。不过我还是要再看看TCP/IP vol1,还有好多要学啊:)

论坛徽章:
0
6 [报告]
发表于 2003-02-18 08:35 |只看该作者

关于TCP有序传输的问题

我的意思就是说
如果是用short表示长度的话
那么选
short len;
if recv(socketid,len,2)!=2  //选接收长度
    return error;

再根据长度接收内容
以下是以前写的例子

  1. // ---------------------------------------------------------------------------------------------
  2. //                从端口中读入数据包 包格式为:
  3. //                        前两个字节是包长度,后面是包内容//                param:
  4. //                Param:
  5. //                        Socketid, target user socket id
  6. //                        Msg:                the char buf to save the recv info
  7. //                        msglen:        the char buf length,to prevent buf over flow
  8. //                        Sec                :the time whhile wait for the msg
  9. //                returnL        -1        socket error,
  10. //                                >;0   the msg recv
  11. // ---------------------------------------------------------------------------------------------
  12. int TcpCommClass::RecvPackage (const int SocketId, char *Msg,const int MsgLen) const
  13. {
  14.   fd_set FDSet;
  15.   TIMEVAL TimeVal;

  16.   TimeVal.tv_sec = RecvTimeout;
  17.   TimeVal.tv_usec = 0;

  18.   FD_ZERO (&FDSet);
  19.   FD_SET (SocketId, &FDSet);

  20.   if (select (0, &FDSet, NULL, NULL, &TimeVal) != 1)
  21.     return -1;

  22.   short recvlen,recvcount=0;
  23.   if(recv (SocketId, (char*)&recvlen, 2, 0)!=2)
  24.           return -1;

  25.   if(recvlen>;=MsgLen||recvlen<=0)
  26.           return -1;

  27.   memcpy(Msg,&recvlen,2);

  28.   while(recvcount<recvlen){
  29.   TimeVal.tv_sec = 1;
  30.   TimeVal.tv_usec = 0;

  31.   FD_ZERO (&FDSet);
  32.   FD_SET (SocketId, &FDSet);
  33.   
  34.   if (select (0, &FDSet, NULL, NULL, &TimeVal) != 1)
  35.     return -1;
  36.   
  37.    recvcount+=recv(SocketId,Msg+2+recvcount,recvlen-recvcount,0);
  38.   }
  39.   return recvcount;
  40. }

复制代码

论坛徽章:
0
7 [报告]
发表于 2003-02-18 08:35 |只看该作者

关于TCP有序传输的问题

发送的例子

  1. // ---------------------------------------------------------------------------------------------
  2. //                从端口中读入消息,先写两个字节作消息长度再写消息内容
  3. //                        Socketid        :        the target socket
  4. //                        msg                :        the message want to send
  5. //                        msglen        :        how many chars you want to send,if =-1 the send all in the string
  6. //                        sec                :        how many time wait for send
  7. //                return:
  8. //                        true                send success.        false:        send fail
  9. // ---------------------------------------------------------------------------------------------
  10. bool TcpCommClass::SendPackage (const int SocketId, const char *Msg,const int MsgLen) const
  11. {
  12.   fd_set FDSet;
  13.   TIMEVAL TimeVal;

  14.   TimeVal.tv_sec = SendTimeout;
  15.   TimeVal.tv_usec = 0;

  16.   FD_ZERO (&FDSet);
  17.   FD_SET (SocketId, &FDSet);

  18.   if (select (0, NULL, &FDSet, NULL, &TimeVal) != 1)
  19.     return false;

  20.   short sendlen =MsgLen == -1? strlen (Msg):MsgLen;

  21.   if(send(SocketId,(char*)&sendlen,2,0)!=2)
  22.           return false;

  23.   TimeVal.tv_sec = 1;
  24.   TimeVal.tv_usec = 0;

  25.   FD_ZERO (&FDSet);
  26.   FD_SET (SocketId, &FDSet);

  27.   if (select (0, NULL, &FDSet, NULL, &TimeVal) != 1)
  28.     return false;
  29.   return send (SocketId, Msg, sendlen, 0) == sendlen;
  30. }

复制代码

论坛徽章:
0
8 [报告]
发表于 2003-02-18 11:10 |只看该作者

关于TCP有序传输的问题

看了你的代码,获益非浅,不过有些问题,比如,发送端正确发送了长度消息和真正的消息,而接收端一次接收,只收到了1个字节,那么就意味着发送端发送的这一组消息都作废了.

我想是不是因为以上的代码是最简单的,没有考虑任何出错判断呢?

论坛徽章:
0
9 [报告]
发表于 2003-02-18 12:57 |只看该作者

关于TCP有序传输的问题

没有考虑那么多
因为一次发送两个字节
并接收两个总是成功的
不会多次发送
也不需要多次接收

所以我不想把代码写得那么麻烦

而且以上代码在实际应用中也没有出过问题
(当然也是因为在局域网内带宽是100M)

如果你想改进也可以

论坛徽章:
0
10 [报告]
发表于 2003-02-18 14:28 |只看该作者

关于TCP有序传输的问题

对,考虑的问题的确很少,我现在是在广域网环境里面,就必须要考虑到最坏情况,就是接收到1字节的情况,还有就是同时接收到一堆消息的情况。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP