您的位置:首页 > 编程语言

关于socket编程的一点小思考

2011-10-09 16:40 351 查看
有几个问题:

一、为什么在bind的时候需要htons来转换字节序,而以后在send函数发送data的时候却不需要转换了呢?

我思考之后觉得:在开始bind的时候,端口号、IP参数都是以整数形式在进行bind操作,然而在发送数据时,发送、接受时的参数却都是(const )char FAR *buf


这就意味着,发送、接受的不再是以整数形式存在的数据,而是以字符串形式存在的数据;然而不管大端还是小端,在存储字符串时都是一样的,这样就不需要转换,

不同的机器也都能正确识别了。 (在网络上的字符串,字符数组的传输是没有网络字节顺序的。他人的说法)

二、成功连接以后,使用recv/recvfrom函数接收数据,内存的情况是怎样的呢?

一个已经取得连接的TCP socket sockConn 两次接收数据的代码如下:

char buf1[16];

recv(sockConn,buf1,16,0);

MessageBox(buf1);

char buf2[16];

recv(sockConn,buf2,16,0);

MessageBox(buf2);

与sockConn连接的另外一个TCP socketsockClient 两次发送数据的代码如下:

send(sockClient,"sendmessage1",strlen("sendmessage1")+1,0); //包含字符串结束符,共发送13字节。

send(sockClient,"sendmessage2",strlen("sendmessage2"),0); //不包含字符串结束符,共发送12字节。

sockConn的第一个messageBox(buf1);结果是sendmessage1,而第二个MessageBox(buf2);结果是sendmessage2烫烫sendmessage1。这时我就估计到内存的情况应该如下图所示:



也就是说buf2的内存空间刚好排在前一个接收数据容器buf1的前面,我估计这就是所谓的TCP数据流的意义吧,接收到的数据会连在一起,流式的。当使用MessageBox(buf2)输出buf2的时候,就一直输出,直到遇到后面buf1第13个字节的结束符/0为止,所以就看到上面的输出结果了。

看回sockConn第二次接收数据的语句,recv(sockConn,buf2,16,0);参数16是控制接收数据的字节数,其实这个参数并不一定就要是buf的大小,它可以取任何大于0的整数值,如果我把sockClient第二次发送的语句改为:

send(sockClient,"sendmessage2ABCDEF",strlen("sendmessage2ABCDEF"),0); //不包含字符串结束符,共发送18字节。

哪么MessageBox(buf2);的结果就是sendmessage2ABCDsendmessage1,因为recv(sockConn,buf2,16,0);的参数16规定了最多只接收16个字节的数据,所以把数据“EF”丢弃掉。如果把recv(sockConn,buf2,16,0);改为recv(sockConn,buf2,18,0);哪么MessageBox(buf2);的结果就是sendmessage2ABCDEFndmessage1,因为buf2只有16个字节的大小,接收到的第17、18个字节“EF”就跟着buf2的末端继续写入内存,于是就把buf1的“se”改为“EF”了。如果改为recv(sockConn,buf2,20,0);哪么MessageBox(buf2);的结果还是sendmessage2ABCDEFndmessage1,buf1的第三第四个字节空间里面的数据“nd”不会被改写,因为接收到的数据还用不到这里的空间。

简单的说,recv函数的第三个参数就像是一个闸门,接收到的数据写入内存时禁止越过这个闸门,如果闸门前的内存不够写入全部接收到的数据,那就把后面无法写入的哪部分数据丢弃。如果闸门前的内存让全部接收到的数据写入后还有多余的,那多余的内存会保留原本的值,并不会被改写。

甚至还可以改为recv(sockConn,buf2,40,0);buf1加上buf2总共才32个字节,而我把recv的第三个参数改为40,如果sockClient发送了50个字节,前40个字节的内容能成功写入内存。要注意的是,在buf1后面新开辟出来的8个字节内存空间,是在buf2+buf1不够内存写入数据的时候才根据需要开辟的,例如如果sockClient只发送了30个字节,那么buf1后面是不会开辟任何内存空间的。而如果sockClient只发送了37个字节,那么buf1后面只开辟5个字节的内存空间而不是开辟8个字节的内存空间的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: