`
chriszeng87
  • 浏览: 732911 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

socket 中send 和recev函数详解

阅读更多

int send( SOCKET s,      const char FAR *buf,      int len,      int flags ); 

不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。

客户程序一般用send函数向服务器发送请求,而服务器则通常用send函数来向客户程序发送应答。

该函数的第一个参数指定发送端套接字描述符;

第二个参数指明一个存放应用程序要发送数据的缓冲区;

第三个参数指明实际要发送的数据的字节数;

第四个参数一般置0。

这里只描述同步Socket的send函数的执行流程。当调用该函数时,send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果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函数在执行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,
如果在等待时出现网络错误,那么该Socket函数就返回 SOCKET_ERROR)

注意:在Unix系统下,如果send在等待协议传送数据时网络断开的话,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。

通过测试发现,异步socket的send函数在网络刚刚断开时还能发送返回相应的字节数,同时使用select检测也是可写的,但是过几秒钟之后,再send就会出错了,返回-1。
select也不能检测出可写了。

recv函数


int recv( SOCKET s,     char FAR *buf,      int len,     int flags     );  

不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。

该函数的第一个参数指定接收端套接字描述符;

第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;

第三个参数指明buf的长度;

第四个参数一般置0。

这里只描述同步Socket的recv函数的执行流程。当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现
网络错误,那么recv函数返回SOCKET_ERROR,如果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信号,进程对该信号的默认处理是进程终止。

 

int send (
   SOCKET s,             
   const char FAR * buf, 
   int len,              
   int flags             
);

请问send函数每次最多可以发送多少数据?是int的最大值吗?

【sms88】:
不是int的最大值

【sms88】:
理论上视乎是一个窗口大小减去协议头的大小

【xxyyboy】:
不是, send   有不指定长度的,有指定长度的。
int send (
   SOCKET s,                 //连路
   const char FAR * buf,     //buffer 内容
   int len,                   //buffer len
   int flags                 //不知道
);

函数 int 只是表示发送成功失败的返回值,不表示 多长

像你这个就是 有buffer 就发送
recv到的数据流可能是断断续续的,你要把他们放在一起然后解码。

【dodoboy】:
那也就是说如果buffer中的数据过大,我也只需要调用一次send函数,而低层到底是一次传输成功还是陆续传输我不用管了吗?

【mudunke775】:
recv到的数据流可能是断断续续的,你要把他们放在一起然后解码。

//////////////////////////////////////////////////////////////////

解码和合并包是低层做的,不用你自己解码吧?

【unsigned】:
Send 分为阻塞和非阻塞,阻塞模式下,如果正常的话,会直到把你所需要发送的数据发完再返回;非阻塞,会根据你的socket在底层的可用缓冲区的大小,来将你的缓冲区当
中的数据拷贝过去,有多大缓冲区就拷贝多少,缓冲区满了就立即返回,这个时候的返回值,只表示拷贝到缓冲区多少数据,但是并不代表发送多少数据,同时剩下的部分需要
你再次调用send才会再一次拷贝到底层缓冲区。

【iambic】:
和write差不多。

【Arthur_】:
You can use *setsockopt* to enlarge the buffer.


作为一个套接字,它拥有两个缓冲,接收数据缓冲和发送数据缓冲(此缓冲不同与你自己定义的缓冲),当有数据到达时,首先进入的就是接收数据缓冲,然后用户从这个缓冲
中将数据读出来,这就是套接字接受的过程,这个缓冲的大小可以自己用SetSocketOpt()设定,同时操作系统对它有一个默认大小,如果对方在很短时间内发送大量数据到达
这个套接子时,可能它没来得及接收完,因此接收缓冲处于满的状态,再有数据来的时候就进不去了,因此对方的 SEND可能就返回错误,在对方发送的数据量很小时不会出现
这种情况,当数据量很大时,情况就很明显了,很容易造成收不到的情况。  
  同样,发送方的发送缓冲也有相对应的问题。  
  解决这个问题的办法有几种:  
  1:利用SetSocketOpt()函数将接收方套接子接收缓冲设为足够大小;  
  2:在发送方进行数据发送时判断发送是否成功,如果不成功重发;  
  3:要求接收方收到数据后给发送方回应,发送方只在收到回应后才发送下一条数据。 

 

转自:http://hi.baidu.com/posinfo/item/1ed18ecc61ace83499b4984e

分享到:
评论

相关推荐

    Socket send函数和recv函数详解

    不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。

    socket send和recv详解

    Socket 编程中的 send 和 recv 函数详解 在 Socket 编程中,send 和 recv 函数是最基本的网络通信函数。它们用于在客户端和服务端之间传递数据。在 TCP/IP 协议中,send 函数用于将数据发送到服务端,而 recv 函数...

    send函数 和recv函数

    在计算机网络编程中,socket编程是实现进程间通信的一种重要方式,其中`send`函数和`recv`函数是进行数据发送与接收的关键接口。下面将详细阐述这两个函数的工作原理、参数意义以及使用时需要注意的一些细节。 ####...

    Linux C 函数详解

    第二部分(LinuxC函数详解(p131-260).PDF)深入到更复杂的函数和系统调用;第三部分(LinuxC函数详解(p261-411).PDF)可能涉及了高级主题,如多线程编程和异步I/O;第四部分(LinuxC.pdf)可能是全书的概述或索引,...

    socket详解 socket详解 socket详解 socket详解

    Socket 编程详解 在网络编程中,Socket 是一个基本概念, plays a crucial role in building network applications. 在 C# 中,Socket 编程是通过使用 System.Net.Sockets 命名空间中的类和方法来实现的。下面,...

    Socket Send and Receive

    ### Socket中的Send与Receive函数详解 在网络编程领域中,数据的发送与接收是核心操作之一。在本篇文章中,我们将重点探讨如何通过`send`和`recv`这两个基础函数来进行数据传输,虽然也有如Winsock2提供的`WSASend`...

    有关socket编程的函数详解

    ### 有关socket编程的函数详解 #### 一、概述 Socket编程是网络编程的重要组成部分,它使得不同计算机之间可以通过网络进行通信。在Windows环境下,使用socket编程时,我们需要调用一系列特定的API函数来实现这一...

    socket函数详解

    Socket函数详解 Socket编程是计算机网络编程的基础,它允许程序创建和使用网络连接进行通信。在本文中,我们将深入理解socket函数以及相关的数据结构,这对于初学者来说是至关重要的。 首先,我们来看`struct ...

    Socket-send-and-recv-.rar_c socket send recv_socket

    本文将深入探讨"Socket下send和recv使用的说明及介绍"这一主题,帮助开发者更好地理解和运用这两个关键函数。 Socket API提供了send和recv函数,它们是TCP/IP通信的核心组件,用于在套接字之间发送和接收数据。在...

    socket编程头文件和常用函数.doc

    在Linux和其他类Unix系统中,socket编程涉及一系列的头文件和函数,这些头文件和函数共同构成了一个强大的网络编程工具集。 #### 关键头文件概览 - **`sys/types.h`**:此头文件定义了一系列数据类型,如`pid_t`、...

    socket_send2plc.rar_PLC_plcsend_socket send 三菱 plc_三菱PLC

    4. **socket_send函数**:在C/C++的套接字编程中,`socket_send`函数用于向连接的套接字发送数据。在本案例中,可能是将要写入PLC的数据打包成特定格式,然后通过`socket_send`发送到PLC。 5. **plcsend**:这可能...

    拦截网络socket的数据

    描述中提到的“通过HOOK捕获和修改send函数”,这里提到了两种关键概念:HOOK技术和send函数。HOOK是一种编程技术,它允许程序员在某个程序的特定点插入代码来监视或改变其行为。在Windows系统中,比如,可以使用...

    python数据分析与可视化-02-socket之send和recv的原理剖析.ev4.rar

    Python的socket模块提供了一系列的函数和类,用于实现TCP(传输控制协议)和UDP(用户数据报协议)等网络通信协议。在开始使用socket之前,我们需要导入socket模块,并创建一个socket对象。 2. **socket的创建**:...

    socket_send_buf_thread.zip

    在"socket_send_buf_thread.c"和"socket_send_buf_thread.h"这两个源代码文件中,我们很可能看到以下核心概念: 1. **套接字创建**:使用`socket()`函数创建一个socket实例。该函数接收三个参数,分别是协议族(如...

    简单的测试socket函数程序

    在标题中提到的“简单的测试socket函数程序”,我们通常会用到以下两个主要的socket函数: 1. `socket()`:这是创建一个新的socket的函数。它接受两个参数,一个是通信协议族(如AF_INET用于IPv4,AF_INET6用于IPv6...

    socket函数使用说明

    总的来说,`socket函数说明.docx`文档涵盖了Socket编程中的关键函数,对于理解Socket编程原理和实现提供了很大的帮助。无论是新手还是经验丰富的开发者,都能从中受益,更好地理解和应用Socket函数,构建可靠的网络...

    socket tcp连续send会发送失败 什么原因 怎么解决.zip看似丢包其实不是

    socket连续send会发送失败 看似丢包 什么原因 怎么解决.zip

    Socket编程函数说明

    该函数的原型为:`send(socket, data, length, flags)`。 * `socket`:是所用套接字的描述符。 * `data`:是待发送数据在内存中的地址。 * `length`:是一个整数,指定数据的字节数。 * `flags`:包含请求特殊选项...

    Socket常用函数大全

    Socket函数集合为开发人员提供了强大的工具箱,用于创建、配置、管理以及在网络间发送和接收数据。以下是对给定文件中提及的Socket常用函数的详细解析,旨在帮助读者深入理解每个函数的功能与应用场景。 ### accept...

    socket tcp如何防止多次send的包被合成一个包(粘包)发送.zip

    在TCP/IP通信中,"粘包"问题是一个常见的现象,特别是在使用socket编程时。当多个小数据包在传输过程中被合并成一个大包发送,我们就说发生了“粘包”。这通常发生在TCP协议中,因为TCP为了提高网络效率,采用了...

Global site tag (gtag.js) - Google Analytics