C语言中TCP API的使用与实现详解,你掌握了吗?
- 行业动态
- 2025-01-20
- 4685
TCP API 是用于网络通信的编程接口,支持基于传输控制协议(TCP)的数据交互。
C语言中的TCP API
在网络编程中,传输控制协议(TCP)是一种面向连接的、可靠的传输层通信协议,C语言提供了一组广泛的API,用于实现基于TCP的网络通信,这些API通常被称为套接字(socket)API,它们为开发者提供了创建和管理网络连接的能力,本文将详细介绍C语言中常用的TCP相关API,并以表格形式展示关键信息。
关键TCP API及说明
函数名 | 描述 | 参数列表 | 返回值 |
socket() | 创建一个套接字。 | int socket(int domain, int type, int protocol); domain: 地址族(如AF_INET)。 type: 套接字类型(如SOCK_STREAM)。 protocol: 协议(通常为0)。 |
成功返回套接字描述符,失败返回-1。 |
bind() | 绑定套接字到指定IP地址和端口。 | int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); sockfd: 套接字文件描述符。 addr: 指向sockaddr结构体的指针,包含地址和端口信息。 addrlen: 地址结构体的长度。 |
成功返回0,失败返回-1。 |
listen() | 设置套接字为监听模式,准备接受连接。 | int listen(int sockfd, int backlog); sockfd: 套接字文件描述符。 backlog: 请求队列的最大长度。 |
成功返回0,失败返回-1。 |
accept() | 接受一个连接请求,并返回一个新的套接字。 | int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); sockfd: 监听套接字文件描述符。 addr: 指向存储客户端地址的结构体。 addrlen: 地址结构体的长度。 |
成功返回新套接字描述符,失败返回-1。 |
connect() | 向服务器发起连接请求。 | int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); sockfd: 套接字文件描述符。 addr: 指向存储服务器地址的结构体。 addrlen: 地址结构体的长度。 |
成功返回0,失败返回-1。 |
send() | 通过套接字发送数据。 | ssize_t send(int sockfd, const void *buf, size_t len, int flags); sockfd: 套接字文件描述符。 buf: 数据缓冲区。 len: 缓冲区长度。 flags: 标志位(通常为0)。 |
成功返回实际发送的字节数,失败返回-1。 |
recv() | 接收来自套接字的数据。 | ssize_t recv(int sockfd, void *buf, size_t len, int flags); sockfd: 套接字文件描述符。 buf: 数据缓冲区。 len: 缓冲区长度。 flags: 标志位(通常为0)。 |
成功返回实际接收的字节数,失败返回-1。 |
close() | 关闭套接字。 | int close(int sockfd); sockfd: 套接字文件描述符。 |
成功返回0,失败返回-1。 |
shutdown() | 关闭套接字的部分或全部通道。 | int shutdown(int sockfd, int how); sockfd: 套接字文件描述符。 how: 关闭方式(如SHUT_RD、SHUT_WR、SHUT_RDWR)。 |
成功返回0,失败返回-1。 |
示例代码
以下是一个简单的C语言TCP客户端和服务器的示例代码:
服务器端代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> int main() { int server_fd, new_socket; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); // Creating socket file descriptor if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // Forcefully attaching socket to the port 8080 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(8080); // Forcefully attaching socket to the port 8080 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) { perror("bind failed"); exit(EXIT_FAILURE); } if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) { perror("accept"); exit(EXIT_FAILURE); } char buffer[1024] = {0}; int valread = read( new_socket , buffer, 1024); printf("%s ",buffer ); send(new_socket , "Hello from server" , strlen("Hello from server") , 0 ); printf("Hello message sent "); return 0; }
客户端代码:
#include <stdio.h> #include <sys/socket.h> #include <stdlib.h> #include <netinet/in.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> int main(int argc, char const *argv[]) { int sock = 0; struct sockaddr_in serv_addr; char const *hello = "Hello from client"; char buffer[1024] = {0}; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf(" Socket creation error "); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(8080); // Convert IPv4 and IPv6 addresses from text to binary form if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) { printf(" Invalid address/ Address not supported "); return -1; } if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf(" Connection Failed "); return -1; } send(sock, hello, strlen(hello), 0 ); printf("Hello message sent "); int valread = read( sock, buffer, 1024); printf("%s ",buffer ); return 0; }
常见问题FAQs
Q1: 如何选择合适的TCP端口号?
A1: TCP端口号范围从0到65535,其中0到1023是知名端口,需要管理员权限;1024到49151是注册端口,通常由应用程序使用;49152到65535是动态或私有端口,可供临时使用。
Q2: 如何处理TCP连接中的超时问题?
A2: 可以使用setsockopt()函数设置套接字选项来处理超时问题,可以设置接收超时和发送超时。
Q3: TCP三次握手的具体过程是什么?
A3: 第一次握手:客户端发送SYN包到服务器,进入SYN_SENT状态,第二次握手:服务器收到SYN包后,回复SYN+ACK包,进入SYN_RECEIVED状态,第三次握手:客户端收到服务器的SYN+ACK包后,回复一个ACK包,进入ESTABLISHED状态,连接建立完成。
本站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本站,有问题联系侵删!
本文链接:http://www.xixizhuji.com/fuzhu/396878.html