在两台计算机上建立一个网络连接,需要五个要素:本机地址、本机端口、协议类型、远端端口、远端地址,那么如何从一个建立好的连接上获取这些信息呢?就需要用到

getsockname和getpeername这两个函数。

但前提是要在建立好的连接上。

作为客户端,要在正确调用connect()之后,才能使用这两个函数

作为服务端,要在正确调用accept()之后,才能使用这两个函数

以下为测试代码,windows/linux下均可编译运行。

#include <stdint.h>
#include <stdio.h>
#include <memory.h>#ifdef WIN32
#include <windows.h>
typedef int32_t socklen_t;
#define close(x) closesocket(x)
#else
#include <errno.h>
#include <arpa/inet.h>
#include <unistd.h>
#define INVALID_SOCKET (-1)
typedef int32_t SOCKET;
#endifint32_t Errno()
{
#ifdef WIN32return WSAGetLastError();
#elsereturn errno;
#endif
}void test_getname(SOCKET sock, const char *desc)
{printf("%s\n", desc);struct sockaddr_in addr;socklen_t addr_len = sizeof(addr);int32_t ret = getsockname(sock, (struct sockaddr *)&addr, &addr_len);if (ret == 0) {printf("getsockname succ:%s:%d\n", inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));} else {printf("getsockname failed, error = %d\n", Errno());}memset(&addr, 0, sizeof(addr));ret = getpeername(sock, (struct sockaddr *)&addr, &addr_len);if (ret == 0) {printf("getpeername succ:%s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));} else {printf("getpeername failed,error = %d\n", Errno());}
}void test_connect()
{sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("127.0.0.1");addr.sin_port = htons(5000);SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);test_getname(sock, "before connect");inet32_t ret = connect(sock, (sockaddr *)&addr, sizeof(addr));if (ret != 0) {printf("connect error, errno: %d\n", Errno());return;}test_getname(sock, "after connect");close(sock);
}void test_accept()
{SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (INVALID_SOCKET == sock) {printf("create socket error, errno = %d\n", Errno());return;}sockaddr_in srvAddr;memset(&srvAddr, 0, sizeof(srvAddr));srvAddr.sin_family = AF_INET;srvAddr.sin_addr.s_addr = htonl(INADDR_ANY);srvAddr.sin_port = htons(5000);test_getname(sock, "before bind");int32_t ret = bind(sock, (sockaddr *)&srvAddr, sizeof(srvAddr));printf("bind:%s:%d\n", inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port));test_getname(sock, "after bind");if (ret != 0) {printf("bind listen socket error, errno = %d\n", Errno());return;}ret = listen(sock, SOMAXCONN);if (ret != 0) {return;}sockaddr_in cliAddr;socklen_t cliAddrLen = sizeof(cliAddr);SOCKET new_sock = accept(sock, (sockaddr *)&cliAddr, &cliAddrLen);printf("accept:%s:%d\n", inet_ntos(cliAddr.sin_addr), ntohs(cliAddr.sin_port));test_getname(new_sock, "after_accept");close(sock);close(new_sock);
}int32_t main()
{
#ifdef WIN32WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif//test_connect();test_accept();
#ifdef WIN32WSACleanup();
#endifgetchar();return 0;
}

测试结果:

connect:

before connect
getsockname failed,error=10022
getpeername failed,error=10057
after connect
getsockname succ:127.0.0.1:4618
getpeername succ:127.0.0.1:5000

accept:

before bind
getsockname failed,error=10022
getpeername failed,error=10057
bind:0.0.0.0:5000
after bind
getsockname succ:0.0.0.0:5000
getpeername failed,error=10057
accept:127.0.0.1:4630
after accept
getsockname succ:127.0.0.1:5000
getpeername succ:127.0.0.1:4630

getsockname和getpeername测试相关推荐

  1. getsockname与getpeername用法与区别

    getsockname与getpeername是返回套接口关联的本地协议地址和远程协议地址. int getsockname(int sockfd, struct sockaddr * localad ...

  2. getsockname与getpeername

    getsockname与getpeername是返回套接口关联的本地协议地址和远程协议地址. int getsockname(int sockfd, struct sockaddr * localad ...

  3. getsockname和getpeername

    对于TCP服务器来说,如果设置的addr为INADDR_ANY,只有在accept后,用getsockname获得的者是本地分配的真实的ip,即针对已经连接的,而不是监听套接口. 用getpeerna ...

  4. getpeername函数与getsockname函数的介绍

    getpeername函数用于获取与某个套接字关联的外地协议地址 getsockname函数用于获取与某个套接字关联的本地协议地址 函数定义如下: #include<sys/socket.h&g ...

  5. getsockname函数与getpeername函数的使用

    https://www.tuicool.com/articles/V3Avey getsockname和getpeername函数 getsockname函数用于获取与某个套接字关联的本地协议地址  ...

  6. 网编编程必看书籍:unix网络编程

    unix网络编程被誉为圣经,该书主要讲socket套接字相关,socket API,从底层剖析网络编程.网络编程中需要用到的一些经典函数,多路复用函数,这些都值得去反复学习研究. 目录: 录 Part ...

  7. 如何通过数据包套接字攻击Linux内核

    一.前言 最近我花了一些时间使用syzkaller工具对Linux内核中与网络有关的接口进行了模糊测试(fuzz).除了最近发现的DCCP套接字漏洞之外,我还发现了另一个漏洞,该漏洞位于数据包套接字( ...

  8. Winsock编程宝典(转帖)

    --简单的 Winsock 应用程式设计 TCP连接建立与关闭 相信各位读者现在对於 Winsock 的定义.系统环境,以及一些 Winsock Stack及 Winsock 应用程式,都有基本的认识 ...

  9. Unix环境高级编程 笔记

    Unix环境高级编程(第二版)学习笔记 这是一次较长时间的整理,然而跳跃了一些章节和很多知识点,仍然是很不完善很不全面的. 前言 操作系统某些问题 严格意义上,可将操作系统定义为一种软件,它控制计算机 ...

最新文章

  1. SpringBoot使用JSP作为模板
  2. Python代码加密混淆
  3. JS高级——模块化学习笔记
  4. Linux 下 Tomcat 内存大小配置
  5. 趣味java_java-趣味算法
  6. PHP的日期时间函数date()
  7. 黑莓BlackBerry手机刷机ROM常见问题
  8. 圆角正方形 html,ps正方形角怎么变圆角 ps怎么在原来的矩形中改成圆角
  9. OpenCASCADE:Linux平台上构建OCCT使用的第三方库
  10. oracle otm运输管理系统_OTM服务中国十年-Oracle.PDF
  11. 离职“招黑”的6种行为,最后一个太惹人反感!
  12. Android Qcom USB Driver学习(二)
  13. 如何成为一名企业满意的UI设计师
  14. python数据分析学习day08:柱状图
  15. 中 华 百 家 姓 一 览
  16. XMLhttpRequest 请求 XML,JSON ,POJO 数据
  17. Vue环境配置时报npm WARN deprecated bfj-node4@5.3.1: Switch to the `bfj` package for fixes and new features
  18. 苹果变了:Mac 用自研芯片、iPhone 替代车钥匙
  19. 怎么将c语言作业保存到word,C++程序中导出Word文档的简易方法_c语言
  20. UGUI开发实例练习——游戏菜单

热门文章

  1. Mybatis助手之Mybatis-Plus——开始使用
  2. 分布式系统理论基础 - 一致性、2PC和3PC
  3. 1034 Head of a Gang (30 分) One way that the police finds the head of a gang is to check people‘s pho
  4. 算法竞赛入门经典(第二版) | 例题4-5 追踪电子表格中的单元格 (UVa512,Spreadsheet Tracking,World Finals)(解法二)
  5. 罗斯蒙特电磁流量计8723说明书_罗斯蒙特8700系列电磁流量计和传感器的几种类型!...
  6. php mysql读取数组_php实现通用的从数据库表读取数据到数组的函数实例
  7. Redis数据库(二)——数据类型
  8. Redis数据库(一)——介绍、配置与优化
  9. Mysql数据库(四)——mysql索引相关知识
  10. 用c语言设计一个统计字符个数的程序,「第6篇」「C程序上机题」「统计输入的字符个数思路与实现」...