TCP Socket之linux实现
原创一、引言
TCP(传输控制协议)是互联网中广泛使用的一种协议,它提供了一种可靠的数据传输行为。在Linux系统中,我们可以使用socket编程来创建TCP连接,实现客户端与服务器之间的通信。本文将详细介绍Linux下使用TCP Socket编程的方法。
二、TCP Socket基本概念
1. Socket:Socket是网络通信的基本抽象,可以明白为网络通信的接口。在Linux系统中,Socket分为三种类型:流式Socket(stream socket)、数据报Socket(datagram socket)和原始Socket(raw socket)。
2. 流式Socket:流式Socket是最常用的Socket类型,它提供了一种可靠、面向连接的数据传输行为。TCP协议就是一种流式Socket。
3. 数据报Socket:数据报Socket提供了一种不可靠、无连接的数据传输行为。UDP协议就是一种数据报Socket。
4. 原始Socket:原始Socket允许用户直接访问网络层协议,如IP、ICMP等。
本文核心介绍流式Socket编程,即TCP Socket编程。
三、Linux下创建TCP Socket
1. 创建socket描述符
在Linux下,使用socket函数创建socket描述符,该函数原型如下:
c
int socket(int domain, int type, int protocol);
- `domain`:指定socket通信的协议族,如AF_INET描述IPv4,AF_INET6描述IPv6。
- `type`:指定socket类型,如SOCK_STREAM描述流式Socket,SOCK_DGRAM描述数据报Socket。
- `protocol`:指定协议,对于流式Socket,该参数通常为0。
c
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0) {
perror("socket");
exit(1);
}
2. 绑定地址
在创建socket后,需要将socket绑定到一个地址上,以便客户端能够连接到服务器。对于流式Socket,可以使用bind函数实现:
c
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sock_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("bind");
exit(1);
}
3. 监听连接
在绑定地址后,可以使用listen函数监听客户端的连接请求:
c
if (listen(sock_fd, 5) < 0) {
perror("listen");
exit(1);
}
- 第一个参数是socket描述符,第二个参数是最大连接数。
4. 接受连接
使用accept函数接受客户端的连接请求:
c
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int client_sock_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &client_addr_len);
if (client_sock_fd < 0) {
perror("accept");
exit(1);
}
5. 读写数据
在客户端与服务器生成连接后,可以使用send和recv函数进行数据读写:
c
char buffer[1024];
int recv_len = recv(client_sock_fd, buffer, sizeof(buffer), 0);
if (recv_len < 0) {
perror("recv");
exit(1);
}
printf("Received: %s ", buffer);
send(client_sock_fd, "Hello, client!", strlen("Hello, client!"), 0);
6. 关闭连接
在数据传输完成后,需要关闭连接:
c
close(client_sock_fd);
close(sock_fd);
四、Linux下创建TCP客户端
1. 创建socket描述符
c
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0) {
perror("socket");
exit(1);
}
2. 连接到服务器
c
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8080);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(sock_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("connect");
exit(1);
}
3. 读写数据
c
char buffer[1024];
int send_len = send(sock_fd, "Hello, server!", strlen("Hello, server!"), 0);
if (send_len < 0) {
perror("send");
exit(1);
}
recv_len = recv(sock_fd, buffer, sizeof(buffer), 0);
if (recv_len < 0) {
perror("recv");
exit(1);
}
printf("Received: %