
基本 TCP 套接字编程讲解.docx
11页基本 TCP 套接字编程讲解基于 TCP 的套接字编程的所有客户端和服务器端都是从调用socket 开始,它返回一个套接字描述符客户端随后调用connect 函数,服务器端则调用 bind、listen 和accept 函数套接字通常使用标准的close 函数关闭,但是也可以使用 shutdown 函数关闭套接字下面针对套接字编程实现过程中所调用的函数进程分析以下是基于 TCP 套接字编程的流程图:socket 函数套接字是通信端点的抽象,实现端对端之间的通信与应用程序要使用文件描述符访问文件一样,访问套接字需要套接字描述符任何套接字编程都必须调用socket 函数获得套接字描述符,这样才能对套接字进行操作以下是该函数的描述:1. /* 套接字 */ 2. 3. /* 4. * 函数功能:创建套接字描述符; 5. * 返回值:若成功则返回套接字非负描述符,若出错返回-1; 6. * 函数原型: 7. */ 8. #include
TCP 客户端可以调用函数connect 来建立与 TCP 服务器端的一个连接该函数的描述如下:1. /* 2. * 函数功能:建立连接,即客户端使用该函数来建立与服务器的连接; 3. * 返回值:若成功则返回0,出错则返回-1; 4. * 函数原型: 5. */ 6. #include
若 TCP 套接字调用connect 函数将建立 TCP 连接(执行三次握手),而且仅在连接建立成功或出错时才返回,其中出错返回可能有以下几种情况:若 TCP 客户端没有收到 SYN 报文段的响应,则返回 ETIMEOUT 错误;若客户端的 SYN 报文段的响应是 RST (表示复位),则表明该服务器主机在我们指定的端口上没有进程在等待与之连接只是一种硬错误,客户端一接收到 RST 就立即返回ECONNERFUSED 错误;RST 是 TCP 在发生错误时发送的一种 TCP 报文段产生 RST 的三个条件时:目的地为某端口的 SYN 到达,然而该端口上没有正在监听的服务器;TCP 想取消一个已有连接;TCP 接收到一个不存在的连接上的报文段;若客户端发出的 SYN 在中某个路由器上引发一个目的地不可达的 ICMP 错误,这是一个软错误客户端主机内核保存该消息,并在一定的时间间隔继续发送 SYN (即重发)在某规定的时间后仍未收到响应,则把保存的消息(即 ICMP 错误)作为EHOSTUNREACH 或ENETUNREACH 错误返回给进行bind 函数调用函数 socket 创建套接字描述符时,该套接字描述符是存储在它的协议族空间中,没有具体的地址,要使它与一个地址相关联,可以调用函数bind 使其与地址绑定。
客户端的套接字关联的地址一般可由系统默认分配,因此不需要指定具体的地址若要为服务器端套接字绑定地址,可以通过调用函数 bind 将套接字绑定到一个地址下面是该函数的描述:1. /* 套接字的基本操作 */ 2. 3. /* 4. * 函数功能:将协议地址绑定到一个套接字;其中协议地址包含IP地址和端口号; 5. * 返回值:若成功则返回0,若出错则返回-1; 6. * 函数原型: 7. */ 8. #include
一般 TCP 客户端使用内核为其选择一个临时的端口号,而服务器端通过调用bind 函数将端口号与相应的套接字绑定进程可以把一个特定的 IP 地址捆绑到它的套接字上,但是这个 IP 地址必须属于其所在主机的网络接口之一对于 TCP 客户端,这就为在套接字上发送的 IP 数据报指派了源 IP 地址对于 TCP 服务器端,这就限定该套接字只接收那些目的地为这个 IP 地址的客户端连接TCP 客户端一般不把 IP 地址捆绑到它的套接字上当连接套接字时,内核将根据所用外出网络接口来选择源 IP 地址,而所用外出接口则取决于到达服务器端所需的路径若 TCP 服务器端没有把 IP 地址捆绑到它的套接字上,内核就把客户端发送的 SYN 的目的 IP 地址作为服务器端的源 IP 地址在地址使用方面有下面一些限制:在进程所运行的机器上,指定的地址必须有效,不能指定其他机器的地址;地址必须和创建套接字时的地址族所支持的格式相匹配;端口号必须不小于1024,除非该进程具有相应的特权(超级用户);一般只有套接字端点能够与地址绑定,尽管有些协议允许多重绑定;listen 函数在编写服务器程序时需要使用监听函数 listen 。
服务器进程不知道要与谁连接,因此,它不会主动地要求与某个进程连接,只是一直监听是否有其他客户进程与之连接,然后响应该连接请求,并对它做出处理,一个服务进程可以同时处理多个客户进程的连接listen 函数描述如下:1. /* 2. * 函数功能:接收连接请求; 3. * 函数原型: 4. */ 5. #include
内核为任何一个给定监听套接字维护两个队列:未完成连接队列,每个这样的 SYN 报文段对应其中一项:已由某个客户端发出并到达服务器,而服务器正在等待完成相应的 TCP 三次握手过程这些套接字处于 SYN_REVD 状态;已完成连接队列,每个已完成 TCP 三次握手过程的客户端对应其中一项这些套接字处于 ESTABLISHED 状态;accept 函数accept 函数由 TCP 服务器调用,用于从已完成连接队列队头返回下一个已完成连接如果已完成连接队列为空,那么进程被投入睡眠该函数的返回值是一个新的套接字描述符,返回值是表示已连接的套接字描述符,而第一个参数是服务器监听套接字描述符一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在内核为每个由服务器进程接受的客户连接创建一个已连接套接字(表示 TCP 三次握手已完成),当服务器完成对某个给定客户的服务时,相应的已连接套接字就会被关闭该函数描述如下:1. /* 函数功能:从已完成连接队列队头返回下一个已完成连接;若已完成连接队列为空,则进程进入睡眠; 2. * 函数原型: 3. */ 4. int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);//返回值:若成功返回套接字描述符,出错返回-1; 5. /。
