发表于:2009/7/8 1:26:20
#0楼
/*
* packets are illusions (在winsock中信息包的处理的多种联想)
*/
this problem comes up in various guises:(多种版本的理解)
* my client program sent 100 bytes, but the server program only got 50.
* my client program sent several small packets, but the server program received one large packet..
* how can i find out how many bytes are waiting on a given socket, so i can set up a receive buffer for the size of the packet?
(* ,客户端发送100字节,但是服务器编程只收到50个字节
* 客户程序发送一些小的包,但服务器程序却收到一个大包
* 怎样才能找出有多少个字节正在等待被接收在一个套接字中, 从而能建立一个大小刚好等于发送过来的数据的缓冲.
i think that understanding this issue is one of tcp/ips rites of passage.
(我认为搞明白上面的问题,是成为一个合格的网络程序员的一个入门仪式)
the core concept that you must grasp is that tcp is a stream protocol. this means that if you send 100 bytes, the receiving end could receive all byte chunks. or, the receiver could receive that 100 byte block plus some data from the previous send and some from the succeding send.
(这个核心的概念是你必顺领会到tcp是一个流协议. 它意味着如果你发送100个字节,那么接收方最后能接收到所有的100个字节.
或者, 接收方可能接收到的是100个字节块再加上之前发送方成功发送过来的一些数据.
so, you ask, how can you make a program receive whole packets only?
你也许会问, 怎样编程来实现只接收某个特定的信息包呢?
the easiest method is to prefix each packet with a length value. for example, you could prefix every packet with a 2-byte unsigned integer that tells how long the packet is. length prefixes are most effective when the data in each protocol packet has no particular structure, such as raw binary data. see this example for code that reads length-prefixed packets from a tcp stream(
recv_packet.cpp.rar
).
(最轻松的方法是在每个信息包的的前面加上一个反应包大小的数据, 例如,你能在每个包的前面加上一个2字节长的无符号整数(16位),
这种编程模型在要发送很多不同大小的编程时定义的数据结构时最为有效.
another method for setting up packets on top of a stream protocol is called delimiting. each packet you send in such a scheme is followed by a unique delimiter. the trick is to think of a good delimiter; it must be a character or string of characters that will never occur inside a packet.
some good examples of delimited protocols are nntp, pop3, and smtp,
all of which use a carriage-return/line-feed(crlf) pair as their delimiter.
delimiting generally only works well with text-based protocols
, because by design they limit themselves to a subset of all the legal characters, that leaves plenty of possible delimiters to choose from.
(另一种方法是在包的前面,后面或者前后都加上特定的字符代表包的开始和结尾,一般都用不可见的控制字符,如回车,一般称之为 定界协议 , 使用这种编程模型的有nntp,pop3 和smtp等. 它们都是用\n\r 换行加回车(crlf)作为包之间的定界符. 定界符的方法只用在基于文本的协议.
its also possible to have a mixed approach. http, for example, has crlf-delimited headers, one of which can be content-length, which is a length prefix for the data following the headers.
也可以把上面两种方法混合在一起, 比如http, 一个有crlf定界符头,再加上一个反应包的内容长度的数据项,的 每一个
of these two methods, i prefer length-prefixing, because delimiting requires your program to blindly read until it finds the end of the packet, whereas length prefixing lets the program start dealing with the packet just as soon as the length prefix comes in. on the other hand, delimiting schemes lend themselves to flexibility, if you design the protocol like a computer language; this implies that your protocols parsers will be complex.
there are a couple of other concerns for properly handling packets atop tcp. first, always check the return value of recv(), which indicates how many bytes it placed in your buffer — it may well return fewer bytes than you expect. second, dont try to
peek
into the winsock stacks buffers to see if a complete packet has arrived. for various reasons, peeking causes problems. instead, read all the data directly into your applications buffers and process it there.
原文:
http://tangentsoft.net/wskfaq/articles/effective-tcp.html
http://tangentsoft.net/wskfaq/examples/packetize.html
(recv_packet 例子)
----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=93132&Name=zjcsharp
* packets are illusions (在winsock中信息包的处理的多种联想)
*/
this problem comes up in various guises:(多种版本的理解)
* my client program sent 100 bytes, but the server program only got 50.
* my client program sent several small packets, but the server program received one large packet..
* how can i find out how many bytes are waiting on a given socket, so i can set up a receive buffer for the size of the packet?
(* ,客户端发送100字节,但是服务器编程只收到50个字节
* 客户程序发送一些小的包,但服务器程序却收到一个大包
* 怎样才能找出有多少个字节正在等待被接收在一个套接字中, 从而能建立一个大小刚好等于发送过来的数据的缓冲.
i think that understanding this issue is one of tcp/ips rites of passage.
(我认为搞明白上面的问题,是成为一个合格的网络程序员的一个入门仪式)
the core concept that you must grasp is that tcp is a stream protocol. this means that if you send 100 bytes, the receiving end could receive all byte chunks. or, the receiver could receive that 100 byte block plus some data from the previous send and some from the succeding send.
(这个核心的概念是你必顺领会到tcp是一个流协议. 它意味着如果你发送100个字节,那么接收方最后能接收到所有的100个字节.
或者, 接收方可能接收到的是100个字节块再加上之前发送方成功发送过来的一些数据.
so, you ask, how can you make a program receive whole packets only?
你也许会问, 怎样编程来实现只接收某个特定的信息包呢?
the easiest method is to prefix each packet with a length value. for example, you could prefix every packet with a 2-byte unsigned integer that tells how long the packet is. length prefixes are most effective when the data in each protocol packet has no particular structure, such as raw binary data. see this example for code that reads length-prefixed packets from a tcp stream(
recv_packet.cpp.rar
).
(最轻松的方法是在每个信息包的的前面加上一个反应包大小的数据, 例如,你能在每个包的前面加上一个2字节长的无符号整数(16位),
这种编程模型在要发送很多不同大小的编程时定义的数据结构时最为有效.
another method for setting up packets on top of a stream protocol is called delimiting. each packet you send in such a scheme is followed by a unique delimiter. the trick is to think of a good delimiter; it must be a character or string of characters that will never occur inside a packet.
some good examples of delimited protocols are nntp, pop3, and smtp,
all of which use a carriage-return/line-feed(crlf) pair as their delimiter.
delimiting generally only works well with text-based protocols
, because by design they limit themselves to a subset of all the legal characters, that leaves plenty of possible delimiters to choose from.
(另一种方法是在包的前面,后面或者前后都加上特定的字符代表包的开始和结尾,一般都用不可见的控制字符,如回车,一般称之为 定界协议 , 使用这种编程模型的有nntp,pop3 和smtp等. 它们都是用\n\r 换行加回车(crlf)作为包之间的定界符. 定界符的方法只用在基于文本的协议.
its also possible to have a mixed approach. http, for example, has crlf-delimited headers, one of which can be content-length, which is a length prefix for the data following the headers.
也可以把上面两种方法混合在一起, 比如http, 一个有crlf定界符头,再加上一个反应包的内容长度的数据项,的 每一个
of these two methods, i prefer length-prefixing, because delimiting requires your program to blindly read until it finds the end of the packet, whereas length prefixing lets the program start dealing with the packet just as soon as the length prefix comes in. on the other hand, delimiting schemes lend themselves to flexibility, if you design the protocol like a computer language; this implies that your protocols parsers will be complex.
there are a couple of other concerns for properly handling packets atop tcp. first, always check the return value of recv(), which indicates how many bytes it placed in your buffer — it may well return fewer bytes than you expect. second, dont try to
peek
into the winsock stacks buffers to see if a complete packet has arrived. for various reasons, peeking causes problems. instead, read all the data directly into your applications buffers and process it there.
原文:
http://tangentsoft.net/wskfaq/articles/effective-tcp.html
http://tangentsoft.net/wskfaq/examples/packetize.html
(recv_packet 例子)
----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=93132&Name=zjcsharp