【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,如需转载请自行联系原作者

相关文章
|
8天前
|
监控 网络协议 Linux
在Linux中,如何实时抓取并显示当前系统中tcp 80 端口的网络数据信息?
在Linux中,如何实时抓取并显示当前系统中tcp 80 端口的网络数据信息?
|
11天前
|
网络协议 安全 算法
"网络世界的守护者:一探究竟TCP协议如何确保数据传输的绝对安全与可靠"
【8月更文挑战第20天】传输控制协议(TCP)是网络通信中的核心协议之一,它确保数据包能可靠、有序地从源头传输到目的地。TCP采用三次握手的方式建立连接,并通过序列号、确认应答及超时重传来保障数据传输的准确性。此外,TCP还具备流量控制与拥塞控制功能,避免网络拥塞。虽然TCP在可靠性上表现优异,但在快速传输场景中可能存在局限。深入理解TCP对于网络工程师和开发者至关重要。
29 1
|
12天前
|
网络协议 Java
一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
这篇文章全面讲解了基于Socket的TCP网络编程,包括Socket基本概念、TCP编程步骤、客户端和服务端的通信过程,并通过具体代码示例展示了客户端与服务端之间的数据通信。同时,还提供了多个案例分析,如客户端发送信息给服务端、客户端发送文件给服务端以及服务端保存文件并返回确认信息给客户端的场景。
一文讲明TCP网络编程、Socket套接字的讲解使用、网络编程案例
|
6天前
|
网络协议 编译器 Go
揭秘!TCP、RPC、gRPC、HTTP大PK,谁才是网络通信界的超级巨星?一篇文章带你秒懂!
【8月更文挑战第25天】本文以教程形式深入对比了TCP、RPC、gRPC与HTTP这四种关键通信协议,并通过Go语言中的示例代码展示了各自的实现方法。TCP作为一种可靠的传输层协议,确保了数据的完整性和顺序性;RPC与gRPC作为远程过程调用框架,特别适合于分布式系统的函数调用与数据交换,其中gRPC在性能和跨语言支持方面表现出色;HTTP则是广泛应用于Web浏览器与服务器通信的应用层协议。选择合适的协议需根据具体需求综合考量。
49 0
|
10天前
|
网络协议
计算机网络:TCP协议的三次握手和四次挥手与UDP协议区别.
计算机网络:TCP协议的三次握手和四次挥手与UDP协议区别.
20 0
|
10天前
|
机器学习/深度学习 网络协议 安全
在Linux中,如何追踪TCP连接和网络数据包,如使用tcpdump或Wireshark?
在Linux中,如何追踪TCP连接和网络数据包,如使用tcpdump或Wireshark?
|
12天前
|
监控
【网络编程】poll函数
【网络编程】poll函数
13 0
|
12天前
|
监控
【网络编程】select函数
【网络编程】select函数
25 0
|
2月前
|
网络协议 安全 Java
Java中的网络编程:Socket编程详解
Java中的网络编程:Socket编程详解
|
2月前
|
网络协议 安全 Java
Java中的网络编程:Socket编程详解
Java中的网络编程:Socket编程详解
下一篇
云函数