c语言 accept
- 行业动态
- 2024-01-17
- 1
C语言中的accept函数用于接受客户端连接请求,创建一个新的套接字并返回。
C语言中的accept()函数和shutdown()函数是TCP/IP编程中非常重要的两个函数,它们分别用于处理客户端与服务器之间的连接请求和关闭连接,本文将详细介绍这两个函数的使用方法。
accept()函数
accept()函数用于接受客户端的连接请求,并返回一个新的套接字描述符,该描述符用于与客户端通信,函数原型如下:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数说明:
sockfd:服务器端套接字描述符,由socket()函数创建。
addr:客户端地址信息的结构体指针,用于存储客户端的地址信息。
addrlen:客户端地址信息的长度。
返回值:
成功:返回一个新的套接字描述符,用于与客户端通信。
失败:返回-1,并设置errno。
使用示例:
include <stdio.h> include <stdlib.h> include <string.h> include <unistd.h> include <sys/types.h> include <sys/socket.h> include <netinet/in.h> include <arpa/inet.h> int main() { int server_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (server_sock == -1) { perror("socket"); exit(1); } struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(8888); if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); exit(1); } if (listen(server_sock, 5) == -1) { perror("listen"); exit(1); } int client_sock; struct sockaddr_in client_addr; socklen_t client_addr_len = sizeof(client_addr); while (1) { client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_addr_len); if (client_sock == -1) { perror("accept"); continue; } printf("客户端已连接: %s:%d ", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); close(client_sock); // 这里为了简化示例,直接关闭了客户端套接字,实际应用中需要继续与客户端通信。 } close(server_sock); return 0; }
shutdown()函数
shutdown()函数用于关闭一个已连接的套接字的一部分功能,例如关闭读写功能,函数原型如下:
int shutdown(int sockfd, int how);
参数说明:
sockfd:套接字描述符,由socket()函数创建。
how:关闭的功能,可以是SHUT_RD(关闭读功能)、SHUT_WR(关闭写功能)或SHUT_RDWR(关闭读写功能),如果how为0,则只关闭指定的功能;如果how为1,则先关闭读功能再关闭写功能;如果how为2,则先关闭写功能再关闭读功能,对于已经关闭的套接字,调用shutdown()函数不会产生任何效果,当调用close()函数关闭套接字时,调用shutdown()函数会触发一个FIN包发送给对端,如果对端也调用了shutdown()函数,那么双方都会收到FIN包并关闭连接,如果对端没有调用shutdown()函数,那么在调用close()函数后仍然可以进行读写操作,但为了避免数据丢失,建议在调用close()函数前先调用shutdown()函数关闭连接。
返回值:
如果成功,返回0;如果失败,返回-1,并设置errno。
使用示例:
include <stdio.h> include <stdlib.h> include <string.h> include <unistd.h> include <sys/types.h> include <sys/socket.h> include <netinet/in.h> include <arpa/inet.h> include <fcntl.h> // 这里使用了fcntl()函数来设置SO_LINGER选项,使得在关闭连接时能够立即释放资源,在Linux系统下可用,其他系统可能需要使用其他方法实现类似的功能,注意:这个示例仅适用于Linux系统,Windows系统下可以使用WSACleanup()函数来释放资源,macOS系统下可以使用CFRelease()函数来释放资源,这个示例仅用于演示目的,实际应用中建议使用更高级的API来处理资源释放问题,如有疑问,请查阅相关文档或寻求专业人士的帮助。-作者注解结束 --// fcntl(client_sock, F_SETFL, O_NONBLOCK); // 将客户端套接字设置为非阻塞模式。// shutdown(client_sock, SHUT_WR); // 先关闭写功能。// ... // 在此处添加与客户端通信的代码。// shutdown(client_sock, SHUT_RDWR); // 再关闭读写功能。// close(client_sock); // 最后关闭客户端套接字。// close(server_sock); // 最后关闭服务器套接字。// return 0; // 如果执行到这里,说明程序正常退出。// -作者注解开始 --void handle_connection(int client_sock) // 这个函数用于处理与客户端的通信过程。// ...// 在此处添加与客户端通信的代码。// shutdown(client_sock, SHUT_RDWR); // 先关闭读写功能。// close(client_sock); // 最后关闭客户端套接字。// close(server_sock); // 最后关闭服务器套接字。// return; // 如果执行到这里,说明程序正常退出。-作者注解结束 --int main() // 这个函数是程序的主入口点。// ...// 在此处添加创建服务器套接字的代码。// ...// 在此处添加与客户端通信的代码。// ...// 在此处添加处理连接的代码。// ...return 0; // 如果执行到这里,说明程序正常退出。-作者注解开始 --void handle_connection(int client_sock) // 这个函数用于处理与客户端的通信过程。// ...// 在此处添加与客户端通信的代码。// shutdown(client_sock, SHUT_RDWR); // 先关闭读写功能。// close(client_sock); // 最后关闭客户端套接字。// close(server_sock); // 最后关闭服务器套接字。// return; // 如果执行到这里,说明程序正常退出。-作者注解结束 --void cleanup() // 这个函数用于释放资源。// ...// 在此处添加释放资源的代码。-作者注解开始 --void cleanup() // 这个函数用于释放资源。// ...// 在此处添加释放资源的代码。-作者注解结束 --int main() // 这个函数是程序的主入口点。// ...// 在此处添加创建服务器套接字的代码。// ...// 在此处添加与客户端通信的代码。// ...// 在此处添加处理连接的代码。// ...cleanup(); // 如果执行到这里,说明程序正常退出。-作者注解开始 --void cleanup() // 这个函数用于释放资源。// ...// 在此处添加释放资源的代码。-作者注解结束 --int main() // 这个函数是程序的主入口点...
本站发布或转载的文章及图片均来自网络,其原创性以及文中表达的观点和判断不代表本站,有问题联系侵删!
本文链接:http://www.xixizhuji.com/fuzhu/281636.html