微信搜索“编程笔记本”,获取更多信息
------------- codingbook2020 -------------
前面我们已经学习了进程、线程以及 TCP/IP 协议等相关内容,今天我们就开始学习 TCP 网络编程。
TCP 协议是 TCP/IP 协议族中一个很重要的协议,由于它传输的稳定性,在很多程序中都在使用,例如 HTTP、FTP 等协议都是在 TCP 协议的基础上构建的。接下来我们将介绍 TCP 套接字编程的基础知识,主要有如下几部分:
- 套接字编程的基础知识部分,介绍套接字编程中经常使用的套接字地质结构,对内核和应用层之间的内存数据传递方式进行简单的介绍
- TCP 网络编程的流程部分,简单介绍 TCP 套接字服务器、客户端的编程框架,对
socket()
、bind()
、listen()
、accept()
、connect()
、close()
函数进行介绍,并提及如何使用read()
、write()
函数进行数据的读取和发送 - 通过一个简单的服务器/客户端的例子介绍 TCP 网络编程的基本流程和代码
- 介绍如何对信号进行截取,特别是 SIGPIPE 信号和 SIGINT 信号
目录
文章目录
1. 套接字编程基础知识
在进行套接字编程之前需要对基本的数据结构有所了解。下面我们将介绍套接字地址结构定义的形式以及如何使用套接字的地址结构。
1.1 套接字地址结构
套接字编程需要指定套接字的地址作为参数,不同的协议族有不同的地址结构定义方式。这些地质结构通常以 sockaddr_
开头,每一个协议族有一个唯一的后缀,例如对于以太网,其结构名称为 sockaddr_in
。
1. 通用套接字数据结构
通用套接字地址类型的定义如下,它可以在不同协议族之间进行强制转换。
// 套接字地址结构
struct sockaddr {
sa_family_t sa_family; // 协议族
char sa_data[14]; // 协议族数据
}
上述结构中协议族成员变量 sa_family 的类型是 sa_family_t
,这个类型其实是 unsigned short
类型, typedef unsigned short sa_family_t
,因此成员变量 sa_family 的长度为 16(2+14)个字节。
2. 实际使用的套接字数据结构
在网络程序设计中所使用的函数中几乎所有的套接字函数都用这个结构作为参数,但是使用 struct sockaddr
不方便进行设置。在以太网中,一般采用结构 struct sockaddr_in
进行设置,其定义如下:
// 以太网套接字地址结构
struct sockaddr_in {
u8 sin_len; // 本结构的长度,16
u8 sin_family; // 协议族,通常为AF_INET
u16 sin_port; // 16位端口号,网络字节序
struct in_addr sin_addr; // 32位IP地址
char sin_zero[8]; // 保留
}
其中,struct in_addr
表示 IP 地址结构,定义如下:
// IP地址结构
struct in_addr {
u32 s_addr; // 32位IP地址,网络字节序
}
3. struct sockaddr_in
与 struct sockaddr
的关系
struct sockaddr_in
与 struct sockaddr
的大小是一样的,都是 16 个字节,在进行地址结构设置的时候,通常的方法是利用结构 struct sockaddr_in
进行设置,然后强制转换为结构 struct sockaddr
类型。
2. TCP 网络编程流程
TCP 网络编程是目前比较通用的方式,例如 HTTP 协议、FTP 协议等很多广泛应用的协议均基于 TCP 协议。TCP 协议主要为 C/S 模式,即客户端(C)、服务器(S)模式,这两种模式之间的程序设计流程存在很大差别。
2.1 TCP 网络编程架构
TCP 网络编程有两种模式,一种是服务器模式,另一种是客户端模式。服务器模式创建一个服务程序,等待客户端用户的连接,接收到用户的连接请求后,根据用户的请求进行处理;客户端