当前位置: 首页 > news >正文

网络编程接口bind学习

1、概述

下面2个问题你会怎么回答呢?

1、bind如果绑定0号端口,可以工作么,如果能正常工作,绑定的什么端口
2、客户端可以调用bind么

2、解析

2.1、bind如果绑定0号端口,可以工作么,如果能正常工作,绑定的什么端口

是可以工作的;当使用bind绑定0号端口时,系统会自动选择一个未被占用的临时端口,通常从32768~60999范围内选择。如果程序显示指定非0端口进行绑定,则使用指定端口监听。
例如:select_server程序绑定0号端口,俩次运行分别被分配了34359、43959端口

2.2、客户端可以调用bind么

可以调用bind,并没有规定只有服务端使用bind。

客户端连接服务器,若未显示调用bind,系统会自动为其分配一个临时端口。
客户端连接服务器,若显示调用bind,会使用指定端口和服务端通信。
例如:

1、用nc命令模仿客户端,没有调用bind绑定端口,连接select_server

2、用nc命令模仿客户端,显示调用bind绑定端口,连接select_server

2.3、原理

socket由2部分组成

1、文件描述符fd(int型)

2、内核对象:tcb(包含源ip、源端口号、目标ip、目标端口、协议等信息)

文件描述符fd 和 tcb一一对应

bind作用:通过fd找到内核对象tcb,设置ip、port

2.4、select_server代码

有需要可以下载代码,自己本地编译试试

编译:gcc -o select_server select_main.c

#define _GNU_SOURCE#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <arpa/inet.h>#define INVALID_HANDLE_VALUE (-1)
#define LISTEN_BACKLOG (1024)int main()
{int sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);if(sockfd == INVALID_HANDLE_VALUE){perror("socket creation failed");return -1;}int opt = 1;setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));// 绑定struct sockaddr_in servAddr;servAddr.sin_family = AF_INET;// servAddr.sin_addr.s_addr = inet_addr("192.168.202.223");servAddr.sin_addr.s_addr = htonl(INADDR_ANY);servAddr.sin_port = htons(0);if(-1 == bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr))){perror("bind error");close(sockfd);return -1;}// 监听if(-1 == listen(sockfd, LISTEN_BACKLOG)){perror("listen error");close(sockfd);return -1;}// 获取监听端口struct sockaddr_in bound_addr;socklen_t len = sizeof(bound_addr);if(getsockname(sockfd, (struct sockaddr*)&bound_addr, &len) == 0){printf("server bound port:%d\n", ntohs(bound_addr.sin_port));}else{printf("getsockname failed\n");}// select模型int maxfd = sockfd;fd_set rfds, temp_fds;FD_ZERO(&rfds);FD_SET(sockfd, &rfds);while(1){temp_fds = rfds;int nready = select(maxfd + 1, &temp_fds, NULL, NULL, NULL);if(nready < 0 && errno != EINTR){break;}// 检查新连接if(FD_ISSET(sockfd, &temp_fds)){struct sockaddr_in client_addr;socklen_t addrlen = sizeof(client_addr);int client_fd = accept4(sockfd, (struct sockaddr*)&client_addr, &addrlen, SOCK_NONBLOCK);if(client_fd < 0){if(errno == EAGAIN || errno == EWOULDBLOCK){printf("Error %s\n", strerror(errno));}else{printf("accept4 failed %s\n", strerror(errno));}}else{if(client_fd > maxfd){maxfd = client_fd;}FD_SET(client_fd, &rfds);    // 打印客户端信息printf("client fd:%d ip:%s port:%d\n", client_fd,  inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));}}// 检查已连接的客户端是否有数据for(int sock_client = sockfd + 1; sock_client <= maxfd; ++sock_client){if(FD_ISSET(sock_client, &temp_fds)){char buf[1024] = {0};int n = recv(sock_client, buf, sizeof(buf), 0);if( n < 0){// 发生错误,判断errno是否为EAGAIN EWOULDBLOCKif(errno != EAGAIN && errno != EWOULDBLOCK){printf("Client on fd %d disconnected\n", sock_client);FD_CLR(sock_client, &rfds);close(sock_client);}}else if (n == 0){// 对端关闭FD_CLR(sock_client, &rfds);close(sock_client);continue;}else{// 收到数据buf[n] = '\0';printf("recv data:%s\n", buf);send(sock_client, buf, n, 0);}}}}// 关闭套接字for(int i = sockfd; i <= maxfd; ++i){close(i);}return 0;
}

学习链接:https://github.com/0voice

http://www.lryc.cn/news/607146.html

相关文章:

  • MySQL时间处理完全指南:从存储到查询优化
  • Java向量化
  • 如何处理Y2K38问题
  • 利用 AI 在 iPhone 上实现 App 文本情绪价值评估(上)
  • 【AI应用】 能源保供战:AI大模型如何守护万家灯火?
  • TGD第十篇:当神经网络遇到TGD特征
  • Qt 开发自动化测试框架搭建
  • 【华为机试】34. 在排序数组中查找元素的第一个和最后一个位置
  • OSPF综合大实验
  • python学智能算法(三十))|SVM-KKT条件的数学理解
  • Git基础命令大全
  • C语言数据结构(3)单链表专题1.单链表概述
  • 【论文学习】KAG论文翻译
  • Redis 中 ZipList 的级联更新问题
  • 一篇文章读懂AI Agent(智能体)
  • Python LRU缓存应用与示例
  • 三维协同:体育场馆设计与渲染的独特挑战
  • Web开发-PHP应用TP框架MVC模型路由访问模版渲染安全写法版本漏洞
  • Au速成班-多轨编辑流程
  • 在纯servlet项目中,使用@WebFilter定义了多个filter,如何设置filter的优先级
  • 【PHP 构造函数与析构函数:从基础到高级的完整指南】
  • 【音视频】WebRTC 中的RTP、RTCP、SDP、Candidate
  • 2025年Python Web框架之争:Django、Flask还是FastAPI,谁将主宰未来?
  • HarmonyOS】鸿蒙应用开发中常用的三方库介绍和使用示例
  • 流式输出阻塞原因及解决办法
  • 位运算-面试题01.01.判定字符是否唯一-力扣(LeetCode)
  • 第三方采购流程
  • 机械学习中的一些优化算法(以逻辑回归实现案例来讲解)
  • Python----MCP(MCP 简介、uv工具、创建MCP流程、MCP客户端接入Qwen、MCP客户端接入vLLM)
  • 字节跳动招机器人数据算法研究员-Top Seed