C语言网络编程函数指南(第二篇)

十年开发一朝灵 2024-08-06 15:03:50

在第一篇文章中,我们介绍了如何创建套接字以及如何将其绑定到特定的地址和端口。本文是第二篇,将继续深入探讨网络编程,重点介绍如何监听连接和接受连接。

一、监听连接

1. listen()函数

listen()函数用于将套接字转换为监听套接字,使其能够接受来自客户端的连接请求。

int listen(int sockfd, int backlog);sockfd:由socket()函数创建并绑定到地址的套接字文件描述符。backlog:指定队列的最大长度,用于存放等待处理的连接请求。

返回值:成功时返回0,失败时返回-1。

示例

// 监听连接,最大等待连接数为5if (listen(sock, 5) == -1) { perror("listen failed"); exit(EXIT_FAILURE);}

二、接受连接

1. accept()函数

accept()函数用于从已完成连接队列中接受一个连接请求,并返回一个新的套接字文件描述符,用于与客户端通信。

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);sockfd:监听套接字的文件描述符。addr:指向sockaddr结构的指针,用于存储客户端的地址信息。addrlen:指向sockaddr结构长度的指针。

返回值:成功时返回新的连接套接字文件描述符,失败时返回-1。

2. sockaddr结构

与绑定地址时使用的sockaddr结构相同,accept()函数也使用这个结构来获取客户端的地址信息。

示例

struct sockaddr_in client_addr;socklen_t client_addr_len = sizeof(client_addr);// 接受客户端连接int client_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addr_len);if (client_sock == -1) { perror("accept failed"); exit(EXIT_FAILURE);}// 打印客户端IP地址和端口号printf("Client connected: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

三、并发处理连接

在实际应用中,服务器通常需要处理多个客户端连接。为了实现这一点,服务器程序通常会为每个接受的连接创建一个新的线程或进程,以便并行处理。

示例:创建线程处理连接

void *handle_connection(void *arg) { int client_sock = *(int *)arg; // 处理客户端连接 // ... close(client_sock); // 处理完毕后关闭连接 return NULL;}// 接受客户端连接int client_sock = accept(sock, (struct sockaddr *)&client_addr, &client_addr_len);if (client_sock == -1) { perror("accept failed"); exit(EXIT_FAILURE);}// 创建线程处理连接pthread_t thread_id;if (pthread_create(&thread_id, NULL, handle_connection, &client_sock) != 0) { perror("pthread_create failed"); close(client_sock);}

四、总结

本篇文章介绍了如何使用listen()函数将套接字设置为监听状态,以及如何使用accept()函数接受客户端的连接请求。这两个函数是服务器端网络编程的关键步骤,它们使得服务器能够被动地等待并接受来自客户端的连接。在下一篇文章中,我们将介绍如何使用套接字进行数据的发送和接收。

1 阅读:58

十年开发一朝灵

简介:感谢大家的关注