2024年4月16日发(作者:)
竭诚为您提供优质文档/双击可除
socket接收函数send
篇一:socketsend函数和recv函数详解
intsend(socKeTs,constcharFAR*buf,intlen,intflags);
不论是客户还是服务器应用程序都用send函数来向Tcp连
接的另一端发送数据。
客户程序一般用send函数向服务器发送请求,而服务
器则通常用send函数来向客户程序发送应答。
该函数的第一个参数指定发送端套接字描述符;
第二个参数指明一个存放应用程序要发送数据的缓冲
区;
第三个参数指明实际要发送的数据的字节数;
第四个参数一般置0。
这里只描述同步socket的send函数的执行流程。当调
用该函数时,send先比较待发送数据的长度len和套接字s
1 18
的发送缓冲的长度,如果len大于s的发送缓冲区的长度,
该函数返回socKeT_eRRoR;如果len小于或者等于s的发送
缓冲区的长度,那么send先检查协议是否正在发送s的发
送缓冲中的数据,如果是就等待协议把数据发送完,如果协
议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲
中没有数据,那么send就比较s的发送缓冲区的剩余空间
和len,如果len大于剩余空间大小send就一直等待协议把
s的发送缓冲中的数据发送完,如果len小于剩余空间大小
send就仅仅把buf中的数据copy到剩余空间里(注意并不
是send把s的发送缓冲中的数据传到连接的另一端的,而
是协议传的,send仅仅是把buf中的数据copy到s的发送
缓冲区的剩余空间里)。如果send函数copy数据成功,就
返回实际copy的字节数,如果send在copy数据时出现错
误,那么send就返回socKeT_eRRoR;如果send在等待协议
传送数据时网络断开的话,那么send函数也返回
socKeT_eRRoR。
要注意send函数把buf中的数据成功copy到s的发送
缓冲的剩余空间里后它就返回了,但是此时这些数据并不一
定马上被传到连接的另一端。如果协议在后续的传送过程中
出现网络错误的话,那么下一个socket函数就会返回
socKeT_eRRoR。(每一个除send外的socket函数在执行的
最开始总要先等待套接字的发送缓冲中的数据被协议传送
2 18
完毕才能继续,如果在等待时出现网络错误,那么该socket
函数就返回socKeT_eRRoR)
注意:在unix系统下,如果send在等待协议传送数据
时网络断开的话,调用send的进程会接收到一个sIgpIpe
信号,进程对该信号的默认处理是进程终止。
通过测试发现,异步socket的send函数在网络刚刚断
开时还能发送返回相应的字节数,同时使用select检测也
是可写的,但是过几秒钟之后,再send就会出错了,返回
-1。select也不能检测出可写了。
recv函数
intrecv(socKeTs,charFAR*buf,intlen,intflags);
不论是客户还是服务器应用程序都用recv函数从Tcp
连接的另一端接收数据。
该函数的第一个参数指定接收端套接字描述符;
第二个参数指明一个缓冲区,该缓冲区用来存放recv
函数接收到的数据;
第三个参数指明buf的长度;
第四个参数一般置0。
这里只描述同步socket的recv函数的执行流程。当应
用程序调用recv函数时,recv先等待s的发送缓冲中的数
据被协议传送完毕,如果协议在传送s的发送缓冲中的数据
时出现网络错误,那么recv函数返回socKeT_eRRoR,如果
3 18
s的发送缓冲中没有数据或者数据被协议成功发送完毕后,
recv先检查套接字s的接收缓冲区,如果s接收缓冲区中没
有数据或者协议正在接收数据,那么recv就一直等待,只
到协议把数据接收完毕。当协议把数据接收完毕,recv函数
就把s的接收缓冲中的数据copy到buf中(注意协议接收
到的数据可能大于buf的长度,所以在这种情况下要调用几
次recv函数才能把s的接收缓冲中的数据copy完。recv函
数仅仅是copy数据,真正的接收数据是协议来完成的),recv
函数返回其实际copy的字节数。如果recv在copy时出错,
那么它返回socKeT_eRRoR;如果recv函数在等待协议接收
数据时网络中断了,那么它返回0。
注意:在unix系统下,如果recv函数在等待协议接收
数据时网络断开了,那么调用recv的进程会接收到一个
sIgpIpe信号,进程对该信号的默认处理是进程终止。
/**************************************************
*****************************/
intsend(
socKeTs,
constcharFAR*buf,
intlen,
intflags
4 18
);
请问send函数每次最多可以发送多少数据?是int的
最大值吗?
【sms88】:
不是int的最大值
【sms88】:
理论上视乎是一个窗口大小减去协议头的大小
【xxyyboy】:
不是,send有不指定长度的,有指定长度的。
intsend(
socKeTs,//连路
constcharFAR*buf,//buffer内容
intlen,//bufferlen
intflags//不知道
);
函数int只是表示发送成功失败的返回值,不表示多长
像你这个就是有buffer就发送
recv到的数据流可能是断断续续的,你要把他们放在一
起然后解码。
【dodoboy】:
那也就是说如果buffer中的数据过大,我也只需要调
用一次send函数,而低层到底是一次传输成功还是陆续传
5 18
输我不用管了吗?
【mudunke775】:
recv到的数据流可能是断断续续的,你要把他们放在一
起然后解码。
///////////////////////////////////////////////////
///////////////
解码和合并包是低层做的,不用你自己解码吧?
【unsigned】:
send分为阻塞和非阻塞,阻塞模式下,如果正常的话,
会直到把你所需要发送的数据发完再返回;非阻塞,会根据
你的socket在底层的可用缓冲区的大小,来将你的缓冲区
当中的数据拷贝过去,有多大缓冲区就拷贝多少,缓冲区满
了就立即返回,这个时候的返回值,只表示拷贝到缓冲区多
少数据,但是并不代表发送多少数据,同时剩下的部分需要
你再次调用send才会再一次拷贝到底层缓冲区。
【iambic】:
和write差不多。
【Arthur_】:
Youcanuse*setsockopt*toenlargethebuffer.
作为一个套接字,它拥有两个缓冲,接收数据缓冲和发
送数据缓冲(此缓冲不同与你自己定义的缓冲),当有数据
6 18
到达时,首先进入的就是接收数据缓冲,然后用户从这个缓
冲中将数据读出来,这就是套接字接受的过程,这个缓冲的
大小可以自己用setsocketopt()设定,同时操作系统对它有
一个默认大小,如果对方在很短时间内发送大量数据到达这
个套接子时,可能它没来得及接收完,因此接收缓冲处于满
的状态,再有数据来的时候就进不去了,因此对方的senD
可能就返回错误,在对方发送的数据量很小时不会出现这种
情况,当数据量很大时,情况就很明显了,很容易造成收不
到的情况。
同样,发送方的发送缓冲也有相对应的问题。
解决这个问题的办法有几种:
1:利用setsocketopt()函数将接收方套接子接收缓冲
设为足够大小;2:在发送方进行数据发送时判断发送是否
成功,如果不成功重发;
3:要求接收方收到数据后给发送方回应,发送方只在
收到回应后才发送下一条数据。
篇二:socket函数readwritesend和recv
socket函数readwritesend和
recv20XX-09-2113:10:28阅读492评论0字号:大中小
一旦,我们建立好了tcp连接之后,我们就可以把得到
的fd当作文件描述符来使用。由此网络程序里最基本的函
数就是read和write函数了。
7 18
ssize_twrite(intfd,constvoid*buf,size_tnbytes);
write函数将buf中的nbytes字节内容写入文件描述符
fd.成功时返回写的字节数.失败时返回-1.并设置errno变
量.在网络程序中,当我们向套接字文件描述符写时有两可
能.
1)write的返回值大于0,表示写了部分或者是全部的数
据.这样我们用一个while循环来不停的写入,但是循环过
程中的buf参数和nbyte参数得由我们来更新。也就是说,
网络写函数是不负责将全部数据写完之后在返回的。
2)返回的值小于0,此时出现了错误.我们要根据错误类
型来处理.
如果错误为eInTR表示在写的时候出现了中断错误.
如果为epIpe表示网络连接出现了问题(对方已经关闭
了连接).
为了处理以上的情况,我们自己编写一个写函数来处理
这几种情况.
intmy_write(intfd,void*buffer,intlength)
{
intbytes_left;
intwritten_bytes;
char*ptr;
ptr=buffer;
8 18
bytes_left=length;
while(bytes_left>0)
{
/*开始写*/
written_bytes=write(fd,ptr,bytes_left);
if(written_bytes {
if(errno==eInTR)/*中断错误我们继续写*/
written_bytes=0;
else/*其他错误没有办法,只好撤退了*/
return(-1);
}
bytes_left-=written_bytes;
ptr+=written_bytes;/*从剩下的地方继续写*/
}
return(0);
}
读函数read
ssize_tread(intfd,void*buf,size_tnbyte)
read函数是负责从fd中读取内容.当读成功时,read返
回实际所读的字节数,如果返回的值是0表示已经读到文件
的结束了,小于0表示出现了错误.如果错误为eInTR说明读
是由中断引起的,如果是econnResT表示网络连接出了问题.
9 18


发布评论