socket编程 send()与 recv()函数详解

首先send函数原型

ssize_t send (int fd, const void *buf, size_t n, int flags);
ssize_t recv (int fd, void *buf, size_t n, int flags)

fd表示要发送到的套接字,buf表示要发送的数据的指针头,n表示要发送(接收)的长度,flag是标识一般设为0.
1:send() recv()行为总览以及memset()的重要性
  send()的行为就是从buf处挑选n个字节的数据发送出去,recv()则读取n个字节到buf中。这里需要注意,他们是不对buf里的值进行任何检测的,所以在接收端最好先将buffer置为0,并设置得大于每次接收的buffer的长度
举个栗子:

//发送方
char buffer[10] = "1234567";
send(fd,buffer,3,0);
//接收方
char buffer[10]=“abcdef”;
recv(fd,buffer,3,0)

接收方在接受完成后buffer变为了"123def",没法区分哪些是接收的,
标准做法:

//发送方
char buffer[10] = "1234567";
send(fd,buffer,3,0);
//接收方
char buffer[10]=“abcdef”;
memset(buffer,0,sizeof(buffer));//先都置为空
recv(fd,buffer,3,0)

2:send()函数
对于send函数,返回值等于0表示连接断开,小于0表示错误,大于0表示实际发送成功的字节数。也就是说有可能存在发送的实际字节数小于函数中的n(这是send函数已经结束了,开始执行下一行代码),如果要确保n个字节全部发送出去了,需要写while循环 判断每次发送的字节数累加是多少(一般是能全部发送成功的)。
阻塞模式和非阻塞模式返回值表示的意义相同。
阻塞模式:如果要发送的数据长度小于剩余缓冲区的大小,则直接发送;如果要发送的数据长度大于剩余缓冲区,则阻塞,一直等到缓冲区发送完前几次数据空间变到大于要发送的数据,放入缓冲区,返回成功发送的字节数(可能没有全部成功发送),0表示连接断开,小于0表示错误。
非阻塞模式:如果要发送的数据长度小于剩余缓冲区的大小,则直接发送返回成功数据;如果要发送的数据长度大于剩余缓冲区则返回错误(小于0),0表示连接断开,小于0表示错误。
也就是说阻塞和非阻塞只是模式不同,他们的返回值表示的意义是一样的。
3 recv()函数
recv()函数与send()函数返回值的意义相同。
recv函数在实际操作上会比较复杂,send函数只需要确定要发送的大小,然后发送就行(一般缓冲区是够大的,而且一次性能发送成功)。但是当recv函数从缓冲区读时就有点复杂。
在阻塞模式下:如果缓冲区为空,则阻塞,如果n小于缓冲区的数据长度,那就从缓冲区读n个字节,剩余的留在缓冲区,返回n;如果n等于缓冲区长度则全部读完,缓冲区为空,返回n,如果n大于缓冲区长度,则全部读完,缓冲区为空,返回实际读的长度。
在非阻塞模式下:如果缓冲区为空,则返回错误,其余和阻塞模式相同。

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
send函数recv函数是VC++Socket编程中最常用的两个函数,它们分别用于发送数据和接收数据。 send函数的原型如下: ```c++ int send( SOCKET s, const char* buf, int len, int flags ); ``` 参数说明: - s:需要发送数据的Socket。 - buf:指向包含要发送数据的缓冲区的指针。 - len:要发送的数据的字节数。 - flags:调用方式标志。 返回值说明: - 成功:返回实际发送的字节数。 - 失败:返回SOCKET_ERROR。 recv函数的原型如下: ```c++ int recv( SOCKET s, char* buf, int len, int flags ); ``` 参数说明: - s:需要接收数据的Socket。 - buf:指向接收数据的缓冲区的指针。 - len:要接收的数据的最大字节数。 - flags:调用方式标志。 返回值说明: - 成功:返回实际接收的字节数。 - 失败:返回SOCKET_ERROR。 sendrecv函数的使用方法如下: ```c++ char sendbuf[] = "Hello, world!"; int sendbuflen = sizeof(sendbuf); int sentbytes = 0; sentbytes = send(sock, sendbuf, sendbuflen, 0); if (sentbytes == SOCKET_ERROR) { // 发送失败 } char recvbuf[1024]; int recvbuflen = sizeof(recvbuf); int receivedbytes = 0; receivedbytes = recv(sock, recvbuf, recvbuflen, 0); if (receivedbytes == SOCKET_ERROR) { // 接收失败 } ``` 使用sendrecv函数时需要注意以下几点: - sendrecv函数都是阻塞式的,即程序会一直等待直到发送或接收完所有数据。 - 如果发送或接收的数据量比较大,需要多次调用sendrecv函数。 - 如果发送或接收的数据量比较小,建议使用TCP_NODELAY选项关闭Nagle算法,以提高发送和接收的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值