当前位置: 技术问答>linux和unix
recv的问题~
来源: 互联网 发布时间:2016-08-02
本文导语: 如果我在一台机器上每次send()1000个字节,在另一台机器上想每次recv()1000个字节,该怎么做? 现在遇到的情况是:我每次send()大约1000个字节左右数据(字节数是动态的,可能1000多点,也可能少点),想在另一台...
如果我在一台机器上每次send()1000个字节,在另一台机器上想每次recv()1000个字节,该怎么做?
现在遇到的情况是:我每次send()大约1000个字节左右数据(字节数是动态的,可能1000多点,也可能少点),想在另一台机器上recv()这一千字节的数据,解析后再处理。但是recv()的返回值与send()发送的字节数不一样,比如我send()1000字节的数据,但是recv却返回2000。如何才能准确取出每次send()的值?
谢谢各位高手前来解答~
我是菜鸟~勿鄙视~
现在遇到的情况是:我每次send()大约1000个字节左右数据(字节数是动态的,可能1000多点,也可能少点),想在另一台机器上recv()这一千字节的数据,解析后再处理。但是recv()的返回值与send()发送的字节数不一样,比如我send()1000字节的数据,但是recv却返回2000。如何才能准确取出每次send()的值?
谢谢各位高手前来解答~
我是菜鸟~勿鄙视~
|
这个没办法实现的...
首先无论是send()还是recv()的过程都是,先写到高速缓存里面去,然后由系统的守护进程,每隔一段时间执
行一次刷新操作,将高速缓存中的脏页写到指定的描述符上去,比如磁盘文件,比如socket。所以当send()
1000字节的数据,并且即使send()成功了,也不能保证这1000字节的数据就一次性的写到了socket描述符
中去。或者对端就一次收到这1000字节。
其次,由于TCP是面向字节流的协议,而不是像UDP,SCTP那样的数据包协议,在socket上传送的时候,
都是比特流。所以你这1000字节在底层到底怎么传送,也不确定。可能会被拆分成好几部分,也可能打包
到一个更大字节的流中,例如2000字节。
最后,通常这种问题的解决方案是,在recv()那端循环的读socket,因为recv()的返回值是实际读到的字节数
量。那你就在循环里面累加读到的字节数,什么时候读到1000了,循环退出,这样就能完整读取发端发过来
的数据了。
首先无论是send()还是recv()的过程都是,先写到高速缓存里面去,然后由系统的守护进程,每隔一段时间执
行一次刷新操作,将高速缓存中的脏页写到指定的描述符上去,比如磁盘文件,比如socket。所以当send()
1000字节的数据,并且即使send()成功了,也不能保证这1000字节的数据就一次性的写到了socket描述符
中去。或者对端就一次收到这1000字节。
其次,由于TCP是面向字节流的协议,而不是像UDP,SCTP那样的数据包协议,在socket上传送的时候,
都是比特流。所以你这1000字节在底层到底怎么传送,也不确定。可能会被拆分成好几部分,也可能打包
到一个更大字节的流中,例如2000字节。
最后,通常这种问题的解决方案是,在recv()那端循环的读socket,因为recv()的返回值是实际读到的字节数
量。那你就在循环里面累加读到的字节数,什么时候读到1000了,循环退出,这样就能完整读取发端发过来
的数据了。
|
send() 1000 bytes/次,没法保证。
ssize_t recv(int s, void *buf, size_t len, int flags);
recv() 1000 bytes/次,可以通过 flags=MSG_PEEK 参数来先copy而不cut出来,len设置成1000,然后看 ssize_t实际的值,若成功,则再次调用 recv(), flag = 0来取数据。
ssize_t recv(int s, void *buf, size_t len, int flags);
recv() 1000 bytes/次,可以通过 flags=MSG_PEEK 参数来先copy而不cut出来,len设置成1000,然后看 ssize_t实际的值,若成功,则再次调用 recv(), flag = 0来取数据。