首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

socket描述符的本质,它可以和服务器建立连接?一个服务器和一个客户端的通信中,三个操作符的作用分别是什么?

  • 25-04-24 11:41
  • 4523
  • 7686
blog.csdn.net

 描述符的本质

    socket 描述符(在类 Unix 系统中是一个非负整数,在 Windows 系统中是 SOCKET 句柄)本质上是操作系统为了管理网络连接而分配的一个索引值,它用于标识一个打开的网络套接字,方便后续对该套接字进行读写、关闭等操作。
    socket 描述符(socket descriptor)是可以用于和服务器建立连接的。

 

客户端的 socket 描述符

在客户端,通常会使用一个 socket 描述符来完成与服务器的连接和通信,其创建和使用过程如下:

1. 创建 socket 描述符

客户端首先使用 socket 函数创建一个 socket 描述符,这个描述符代表了客户端用于网络通信的端点。示例代码如下:

  1. #include <sys/socket.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <arpa/inet.h>
  5. #include <unistd.h>
  6. #define PORT 8888
  7. #define SERVER_IP "127.0.0.1"
  8. int main() {
  9. int client_socket;
  10. // 创建客户端 socket 描述符
  11. client_socket = socket(AF_INET, SOCK_STREAM, 0);
  12. if (client_socket == -1) {
  13. perror("socket creation failed");
  14. return -1;
  15. }
  16. // 后续代码...
  17. close(client_socket);
  18. return 0;
  19. }

这里 client_socket 就是客户端创建的 socket 描述符,AF_INET 表示使用 IPv4 地址族,SOCK_STREAM 表示使用面向连接的 TCP 协议。

2. 连接到服务器

客户端使用 connect 函数,通过这个 socket 描述符向服务器发起连接请求:

  1. struct sockaddr_in server_addr;
  2. server_addr.sin_family = AF_INET;
  3. server_addr.sin_port = htons(PORT);
  4. if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
  5. perror("Invalid address/ Address not supported");
  6. return -1;
  7. }
  8. if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
  9. perror("connection failed");
  10. close(client_socket);
  11. return -1;
  12. }

此时,客户端的 client_socket 描述符就与服务器建立了连接,可以用于后续的数据收发。

3. 数据收发和关闭连接

客户端可以使用 send 和 recv 函数通过 client_socket 描述符进行数据的发送和接收,通信结束后使用 close 函数关闭该描述符:

  1. char message[] = "Hello, server!";
  2. if (send(client_socket, message, sizeof(message), 0) == -1) {
  3. perror("send failed");
  4. close(client_socket);
  5. return -1;
  6. }
  7. char buffer[1024];
  8. ssize_t bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
  9. if (bytes_received == -1) {
  10. perror("recv failed");
  11. close(client_socket);
  12. return -1;
  13. }
  14. close(client_socket);

服务器端的 socket 描述符

在服务器端,通常会使用至少两个 socket 描述符来完成与客户端的通信,分别是监听 socket 描述符和连接 socket 描述符。

1. 监听 socket 描述符

服务器首先创建一个监听 socket 描述符,用于监听客户端的连接请求:

  1. #include <sys/socket.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <arpa/inet.h>
  5. #include <unistd.h>
  6. #define PORT 8888
  7. #define BACKLOG 5
  8. int main() {
  9. int listen_socket;
  10. // 创建监听 socket 描述符
  11. listen_socket = socket(AF_INET, SOCK_STREAM, 0);
  12. if (listen_socket == -1) {
  13. perror("socket creation failed");
  14. return -1;
  15. }
  16. struct sockaddr_in server_addr;
  17. server_addr.sin_family = AF_INET;
  18. server_addr.sin_addr.s_addr = INADDR_ANY;
  19. server_addr.sin_port = htons(PORT);
  20. // 绑定地址和端口
  21. if (bind(listen_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
  22. perror("bind failed");
  23. close(listen_socket);
  24. return -1;
  25. }
  26. // 开始监听
  27. if (listen(listen_socket, BACKLOG) == -1) {
  28. perror("listen failed");
  29. close(listen_socket);
  30. return -1;
  31. }
  32. // 后续代码...
  33. close(listen_socket);
  34. return 0;
  35. }

这里的 listen_socket 就是监听 socket 描述符,它的作用是绑定服务器的地址和端口,并开始监听客户端的连接请求。BACKLOG 表示连接请求队列的最大长度。

2. 连接 socket 描述符

当有客户端发起连接请求时,服务器使用 accept 函数从监听队列中取出一个连接请求,并创建一个新的连接 socket 描述符来与该客户端进行通信:

  1. struct sockaddr_in client_addr;
  2. socklen_t client_addr_len = sizeof(client_addr);
  3. int client_socket;
  4. // 接受客户端连接
  5. client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &client_addr_len);
  6. if (client_socket == -1) {
  7. perror("accept failed");
  8. close(listen_socket);
  9. return -1;
  10. }
  11. // 后续代码...
  12. close(client_socket);

client_socket 就是连接 socket 描述符,它代表了服务器与特定客户端之间的连接。服务器可以使用 send 和 recv 函数通过这个描述符与客户端进行数据的收发。

  • 客户端的 socket 描述符:用于创建与服务器的连接,以及后续与服务器之间的数据收发和关闭连接操作。
  • 服务器的监听 socket 描述符:用于绑定服务器的地址和端口,监听客户端的连接请求。
  • 服务器的连接 socket 描述符:当有客户端连接请求到达时,服务器创建该描述符来与特定客户端进行一对一的数据通信。
注:本文转载自blog.csdn.net的已是上好佳的文章"https://blog.csdn.net/hxj_686/article/details/146077695"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

121
服务器
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top