【UNIX网络编程(二)】基本TCP套接字编程函数

简介:

基于TCP客户/server程序的套接字函数图例如以下:


运行网络I/O。一个进程必须做的第一件事就是调用socket函数。指定期望的通信协议类型。

#include <sys/socket.h>

int socket(int family, int type, int protocol);/*返回值:若成功则为非负描写叙述符,若出错则为-1*/

socket函数成功时返回一个小的非负整数值,它与文件描写叙述符类似。把它称为套接字描写叙述符,简称sockfd。family參数指明协议族。被称为协议域。type參数指明套接字类型。

protocol參数应该是某个协议类型常值。或者为0,以选择所给定family和type组合的系统默认值。

各參数列于一下表格:

family 说明 type 说明 protocol 说明
AF_INET IPv4协议 SOCKET_STREAM 字节流套接字 IPPROTO_TCP TCP传输协议
AF_INET6
IPv6协议 SOCK_DGRAM 数据报套接字 IPPROTO_UDP UDP传输协议
AF_LOCAL Unix域协议 SOCK_SEQPACKET 有序分组套接字 IPPROTO_SCTP SCTP传输协议
AF_ROUTE 路由套接字 SOCK_RAM 原始套接字

AF_KEY 秘钥套接字




TCP客户用connect函数来建立与TCPserver的链接。

#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);  /*返回:若成功则为0。若出错则为-1*/

sockfd是由socket函数返回的套接字描写叙述符。第二个、第三个參数各自是一个指向套接字地址结构的指针和该结构的大小。客户在调用函数connect前不必非得调用bind函数,由于假设须要的话,内核会确定源IP地址,并选择一个暂时port号作为源port。假设是TCP套接字,调用connect函数将激发TCP的三路握手过程,并且仅在连接建立成功或出错时才返回,当中出错返回可能有下面几种情况:

a、若TCP客户没有收到SYN分节的响应,则返回ETIMEDOUT错误。

b、若对客户的SYN的响应是RST(表示复位),则表明该server主机在我们指定的port上没有进程在等待与之连接。

c、若客户发出的SYN在中间的某个路由器上引发了一个“destination unreachable”ICMP错误。则觉得是一个软错误。


bind函数把一个本地协议地址赋予一个套接字。对于网际网协议,协议地址是32位的IPv4地址与16位的TCP或UDPport号的组合。


#include <sys/socket.h>

int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);/*返回,成功则为0,出错则为-1*/

第二个參数是一个指向特定于协议的地址结构的指针。第三个參数是该地址结构的长度,对于TCP。调用bind函数能够指定一个port号。或指定一个IP地址,也能够两者都指定。还能够都不指定。

server在启动时捆绑它们的众所周知port。假设一个TCP客户或server未曾调用bind捆绑一个port,当调用connect或listen时。内核就要为对应的套接字选择一个暂时port号。让内核选择暂时port对于TCP客户来说是正常的。除非应用须要一个预留port;而毁于TCPserver来说却极为罕见,由于server是通过他们的众所周知port被大家认识的。

进程能够把一个特定的IP地址捆绑到它的套接字上,只是这个IP地址必须属于其所在主机的网络接口之中的一个。

假设指定port号为0,那么内核就bind被调用时选择一个暂时port。然而假设指定IP地址为通配地址。那么内核将等到套接字已连接TCP或已在套接字上发出数据报时才选择一个IP地址。对于IPv4来说,通配地址由常量INADDR_ANY来指定,其值为0。

注意:假设让内核来为套接字选择一个暂时port号,那么必须注意。函数bind并不返回所选择的值。实际上。因为bind函数的第二个參数有const限定词,它无法返回所选之值。

为了得到内核所选择的这个暂时port值,必须调用函数getsockanme来返回协议地址。


listen函数仅由TCPserver调用,它做两件事:

1、当socket函数创建一个套接字时,它被如果为一个主动套接字,也就是说。它是一个将调用connect发起连接的客户套接字。listen函数把一个未连接的套接字转换成一个被动套接字,指示内核应该受指向该套接字的连接请求。

2、本函数的第二个參数规定了内核应该为对应套接字排队的最大连接个数。

#include <sys/socket.h>

int listen(int sockfd, int backlog);/*返回:若成功则为0。出错则为-1*/

本函数通常应该在调用socket和bind这两个函数之后。并在调用accept函数之前调用。

为理解backlog參数。必须认识到内核为不论什么一个给定的监听套接字维护两个队列:

1、未完毕连接队列。每一个这种SYN分节相应当中一项:已由某个客户发出并到达server,而server正在等待完毕相应的TCP三路握手过程,这些套接字处于SYN_RCVD状态

2、已完毕连接队列,每一个已完毕TCP三路握手过程的客户相应当中一项。这些套接字处于ESTBLISHED状态。


accept函数由TCPserver调用,用于从已完毕连接队列返回下一个已完毕连接。假设已完毕连接队列为空,那么进程被投入睡眠。

#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);   /*返回:若成功则为负描写叙述符。若出错则为-1*/

參数cliaddr和addrlen用来返回已连接的对端进程协议地址。假设accept成功,那么其返回值是由内核自己主动生成的一个全新描写叙述符,代表与所返回客户的TCP链接。在讨论accept函数时,称第一个參数为监听套接字描写叙述符。称返回值为已连接套接字描写叙述符。区分这两个套接字很重要。

一个server通常只创建一个监听套接字,它在该server的生命周期内一直存在。

内核为每一个由server进程接受的客户连接创建一个已连接套接字。当server完毕对某个给定客户的服务时,对应的一两节套接字就被关闭。

本函数最多返回3个值:一个既可能是新套接字描写叙述符也可能是出错仅仅是的整数、客户进程的协议地址以及该地址的大小。假设对返回客户协议地址不感兴趣,能够把cliaddr和addrlen均置为空指针。


close函数用来关闭套接字。并终止TCP连接。int close(int sockfd)。返回:成功则为0。出错则为-1。





本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5225231.html,如需转载请自行联系原作者

相关文章
|
10天前
|
网络协议 C语言
C语言 网络编程(十三)并发的TCP服务端-以进程完成功能
这段代码实现了一个基于TCP协议的多进程并发服务端和客户端程序。服务端通过创建子进程来处理多个客户端连接,解决了粘包问题,并支持不定长数据传输。客户端则循环发送数据并接收服务端回传的信息,同样处理了粘包问题。程序通过自定义的数据长度前缀确保了数据的完整性和准确性。
|
10天前
|
网络协议 C语言
C语言 网络编程(十一)TCP通信创建流程---服务端
在服务器流程中,新增了绑定IP地址与端口号、建立监听队列及接受连接并创建新文件描述符等步骤。`bind`函数用于绑定IP地址与端口,`listen`函数建立监听队列并设置监听状态,`accept`函数则接受连接请求并创建新的文件描述符用于数据传输。套接字状态包括关闭(CLOSED)、同步发送(SYN-SENT)、同步接收(SYN-RECEIVE)和已建立连接(ESTABLISHED)。示例代码展示了TCP服务端程序如何初始化socket、绑定地址、监听连接请求以及接收和发送数据。
|
10天前
|
网络协议 C语言
C语言 网络编程(十四)并发的TCP服务端-以线程完成功能
这段代码实现了一个基于TCP协议的多线程服务器和客户端程序,服务器端通过为每个客户端创建独立的线程来处理并发请求,解决了粘包问题并支持不定长数据传输。服务器监听在IP地址`172.17.140.183`的`8080`端口上,接收客户端发来的数据,并将接收到的消息添加“-回传”后返回给客户端。客户端则可以循环输入并发送数据,同时接收服务器回传的信息。当输入“exit”时,客户端会结束与服务器的通信并关闭连接。
|
10天前
|
网络协议 C语言
C语言 网络编程(十二)TCP通信创建-粘包
TCP通信中的“粘包”现象指的是由于协议特性,发送方的数据包被拆分并在接收方按序组装,导致多个数据包粘连或单个数据包分割。为避免粘包,可采用定长数据包或先传送数据长度再传送数据的方式。示例代码展示了通过在发送前添加数据长度信息,并在接收时先读取长度后读取数据的具体实现方法。此方案适用于长度不固定的数据传输场景。
|
10天前
|
缓存 网络协议 网络性能优化
C语言 网络编程(二)TCP 协议
TCP(传输控制协议)是一种面向连接、可靠的传输层协议,通过校验和、序列号、确认应答等机制确保数据完整性和可靠性。通信双方需先建立连接,再进行通信,采用三次握手建立连接,四次挥手断开连接。TCP支持任意字节长度的数据传输,具备超时重传、流量控制及拥塞控制机制。三次握手用于同步序列号和确认双方通信能力,四次挥手则确保双方均能完成连接关闭操作,保证数据传输的可靠性。
|
10天前
|
网络协议 C语言
C语言 网络编程(十)TCP通信创建流程---客户端
在TCP通信中,客户端需通过一系列步骤与服务器建立连接并进行数据传输。首先使用 `socket()` 函数创建一个流式套接字,然后通过 `connect()` 函数连接服务器。连接成功后,可以使用 `send()` 和 `recv()` 函数进行数据发送和接收。最后展示了一个完整的客户端示例代码,实现了与服务器的通信过程。
|
7天前
|
网络协议
网络协议概览:HTTP、UDP、TCP与IP
理解这些基本的网络协议对于任何网络专业人员都是至关重要的,它们不仅是网络通信的基础,也是构建更复杂网络服务和应用的基石。网络技术的不断发展可能会带来新的协议和标准,但这些基本协议的核心概念和原理将继续是理解和创新网络技术的关键。
23 0
|
20天前
|
网络协议 编译器 Go
揭秘!TCP、RPC、gRPC、HTTP大PK,谁才是网络通信界的超级巨星?一篇文章带你秒懂!
【8月更文挑战第25天】本文以教程形式深入对比了TCP、RPC、gRPC与HTTP这四种关键通信协议,并通过Go语言中的示例代码展示了各自的实现方法。TCP作为一种可靠的传输层协议,确保了数据的完整性和顺序性;RPC与gRPC作为远程过程调用框架,特别适合于分布式系统的函数调用与数据交换,其中gRPC在性能和跨语言支持方面表现出色;HTTP则是广泛应用于Web浏览器与服务器通信的应用层协议。选择合适的协议需根据具体需求综合考量。
94 0
|
4月前
|
机器学习/深度学习 人工智能 网络协议
TCP/IP五层(或四层)模型,IP和TCP到底在哪层?
TCP/IP五层(或四层)模型,IP和TCP到底在哪层?
77 4
|
监控 网络协议 网络架构
IP协议【图解TCP/IP(笔记九)】
IP协议【图解TCP/IP(笔记九)】
102 0