千家信息网

linux中socket通讯如何获取本地的源端口号

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,这篇文章主要为大家展示了"linux中socket通讯如何获取本地的源端口号",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"linux中socket通讯如何
千家信息网最后更新 2025年12月02日linux中socket通讯如何获取本地的源端口号

这篇文章主要为大家展示了"linux中socket通讯如何获取本地的源端口号",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"linux中socket通讯如何获取本地的源端口号"这篇文章吧。

关于TCP IP网络通讯的资料非常多,TCP IP通过IP数据包模式进行端对端通讯。典型的TCP数据包如下

可以看到数据包包含了源端口号和目的端口号,客户端socket向服务端发起连接时,系统会给socket随机分配一个源端口号,我们可以通过getsocketname来获取连接成功的socket的原端口信息。

函数原型

#include  int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

参数:

sockfd socket连接的句柄

addr 网络地址指针,用来存储本地端socket地址信息,

addrlen addr的空间大小

返回结果,如果调用成功,返回0,并将本地网络地址信息存放在addr里面,失败返回-1,并通过errno反应错误信息。

source_port.cpp

#include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  void safe_close(int &sock); int main(int argc, char *argv[]) {  int sockfd = 0, n = 0;  socklen_t len = 0;  char host[512] = {0};  char buf[1024] = {0};  struct hostent *server;  struct sockaddr_in serv_addr, loc_addr;  if (argc < 2) {   printf("Please input host name\n");   exit(-1);  }  strncpy(host, argv[1], sizeof(host));  server = gethostbyname(host);// 判断输入的域名是否正确  if (NULL == server) {   printf("find host: %s failed.\n", host);   exit(-1);  }  if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0))) {// 创建socket   memset(buf, 0, sizeof(buf));   snprintf(buf, sizeof(buf), "new socket failed. errno: %d, error: %s", errno, strerror(errno));   perror(buf);   exit(-1);  }  memset(&serv_addr, 0, sizeof(serv_addr));  serv_addr.sin_family = AF_INET;  serv_addr.sin_port = htons(80);// http标准端口号  memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);  if (-1 == inet_pton(AF_INET, host, &serv_addr.sin_addr)) {   memset(buf, 0, sizeof(buf));   snprintf(buf, sizeof(buf), "inet_pton failed. errno: %d, error: %s", errno, strerror(errno));   perror(buf);   exit(-1);  }  if (-1 == connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) {// 连接socket   memset(buf, 0, sizeof(buf));   snprintf(buf, sizeof(buf), "connect socket failed. errno: %d, error: %s", errno, strerror(errno));   perror(buf);   exit(-1);  }  printf("connect to %s success.\n", host);  len = sizeof(sizeof(loc_addr));  memset(&loc_addr, 0, len);  if (-1 == getsockname(sockfd, (struct sockaddr *)&loc_addr, &len)) {// 获取socket绑定的本地address信息   memset(buf, 0, sizeof(buf));   snprintf(buf, sizeof(buf), "get socket name failed. errno: %d, error: %s", errno, strerror(errno));   perror(buf);   safe_close(sockfd);   exit(-1);  }  if (loc_addr.sin_family == AF_INET) {// 打印信息   printf("local port: %u\n", ntohs(loc_addr.sin_port));  }  safe_close(sockfd);  return 0; } void safe_close(int &sock) {  if (-1 != sock) {   shutdown(sock, SHUT_RDWR);   sock = -1;  } }

本程序首先会启动一个socket连接一个普通的http服务器(baidu,qq,163,csdn),当socket连通时就通过getsocketname获取连接绑定的本地地址,并通过该地址获取源端口号。

终端1: 编译及运行

$ g++ source_port.cpp$ ./a.out www.baidu.comconnect to www.baidu.com success.local port: 39702

终端2: 通过tcpdump抓包验证

$ sudo tcpdump host www.baidu.com -vtcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes18:38:32.381448 IP (tos 0x0, ttl 64, id 35033, offset 0, flags [DF], proto TCP (6), length 60)icentos.39702 > 220.181.111.188.http: Flags [S], cksum 0x8cd2 (incorrect -> 0x596a), seq 2381397554, win 29200, options [mss 1460,sackOK,TS val 3513497323 ecr 0,nop,wscale 7], length 018:38:32.425904 IP (tos 0x0, ttl 55, id 35033, offset 0, flags [DF], proto TCP (6), length 60)220.181.111.188.http > icentos.39702: Flags [S.], cksum 0xc315 (correct), seq 3561856904, ack 2381397555, win 8192, options [mss 1424,sackOK,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,wscale 5], length 018:38:32.425930 IP (tos 0x0, ttl 64, id 35034, offset 0, flags [DF], proto TCP (6), length 40)

对比终端一和终端二表明获取的源端口地址是正确的。

以上是"linux中socket通讯如何获取本地的源端口号"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

口号 信息 通讯 地址 终端 内容 数据 篇文章 网络 成功 端口 学习 帮助 服务 普通 典型 函数 原型 参数 句柄 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全产品开发流程 厄运峡谷服务器是什么游戏 mysql数据库密码加密了 qt 安卓数据库文件读取 义隆单片机用什么软件开发 自我介绍范文软件开发 下载站用什么服务器 无线网络安全管理和实施 深圳社交电商软件开发 北大图书馆软件开发员的工资 校园网络安全标语百度文库 江苏省信息网络安全协会雨花台 寰球网络技术有限公司 网络安全法举报人 多台电脑连接打印服务器 小规模会计核算软件数据库类型 广东惠发互联网信息科技有限公司 软件开发公司可以报什么项目 员工考核 软件开发 网络安全协议怎么整改 网络安全研究生是学什么的 服务器和群晖nas冲突吗 广东支付软件开发收费 慕尼黑安全会议 网络安全 网络安全李韬 北邮网络安全区块链专业好吗 刀片服务器的硬盘的缓存是多大的 我的世界手游极限生存服务器 数据库连接池数超 git上传到服务器
0