getsockname与getpeername是返回套接口关联的本地协议地址和远程协议地址。

int getsockname(int sockfd, struct sockaddr * localaddr, socken_t * addrlen);

int getpeername(int sockfd, struct sockaddr * peeraddr, socken_t * addrlen);

返回0表示成功,返回1表示出错

参数sockfd表示你要获取的套接口的描述字。

localaddr返回本地协议地址描述结构, peeraddr返回远程协议地址描述结构,addrlen分别是上述2个结构的长度。这个2个函数不难,下面是使用样例

#include <stdafx.h>
#include <stdio.h>
#include <windows.h>
#include <winsock.h>
#pragma comment(lib,"WS2_32");
int main()
{
WSAData tWSAData;
WSAStartup(MAKEWORD(2,2),&tWSAData);
SOCKET CreateSocket;
SOCKET AcceptSocket;
sockaddr_in sockaddr_in_server;
sockaddr_in sockaddr_in_client;
sockaddr_in_server.sin_port = htons(88);
sockaddr_in_server.sin_family = AF_INET;
sockaddr_in_server.sin_addr.S_un.S_addr = INADDR_ANY;//此程序在任何IP上面都可以运行
CreateSocket = socket(AF_INET,SOCK_STREAM,0);
int ret_bind = bind(CreateSocket,(struct sockaddr FAR *)&sockaddr_in_server,sizeof(sockaddr_in));
if (ret_bind != 0)
{
int  WSAGLE = WSAGetLastError();//WSAEADDRINUSE 10048
return WSAGLE;
}
listen(CreateSocket,SOMAXCONN);
printf("等待客户端链接...\n");
int addrlen = sizeof(sockaddr_in);
AcceptSocket = accept(CreateSocket,(struct sockaddr FAR *)&sockaddr_in_client,&addrlen);
int send_data_size;
char buf[] = "这是来自服务器的send";
send_data_size = send(AcceptSocket,buf,sizeof(buf),0);
char bufrecv[30];
int recv_data_size=0;
recv_data_size = recv(AcceptSocket,bufrecv,MAX_PATH,0);
bufrecv[recv_data_size] = '\0';
printf("收到来自客户端的信息:%s\n",bufrecv);
while (strcmp(bufrecv,"exit")!=0 || recv_data_size==SOCKET_ERROR)
{
recv_data_size = recv(AcceptSocket,bufrecv,100,0);//默认是阻塞函数,如果一次send的数据大于一次recv的数据,recv将连续多次获取该数据
bufrecv[recv_data_size] = '\0';
printf("收到来自客户端的信息:%s\n",bufrecv);
sockaddr_in getsockaddr;
int len = sizeof(sockaddr_in);
int r=getsockname(CreateSocket,(sockaddr *)&getsockaddr,&len);
int port=ntohs(getsockaddr.sin_port);
int e = WSAGetLastError();
sockaddr_in getsockaddr2;
int len2 = sizeof(sockaddr_in);
int r2=getpeername(AcceptSocket,(sockaddr *)&getsockaddr2,&len2);
int port2=ntohs(getsockaddr2.sin_port);
int e2 = WSAGetLastError();
}
closesocket(AcceptSocket);
closesocket(CreateSocket);
WSACleanup();
return 0;
}

补充:

1.getsockname和getpeername调度时机很重要,如果调用时机不对,则无法正确获得地址和端口。

2.注意网络字节序和本地字节序

TCP

对于服务器来说,在bind以后就可以调用getsockname来获取本地地址和端口,虽然这没有什么太多的意义。getpeername只有在链接建立以后才调用,否则不能正确获得对方地址和端口,所以他的参数描述字一般是链接描述字而非监听套接口描述字。

对于客户端来说,在调用socket时候内核还不会分配IP和端口,此时调用getsockname不会获得正确的端口和地址(当然链接没建立更不可能调用getpeername),当然如果调用了bind 以后可以使用getsockname。想要正确的到对方地址(一般客户端不需要这个功能),则必须在链接建立以后,同样链接建立以后,此时客户端地址和端口就已经被指定,此时是调用getsockname的时机。

UDP

UDP分为链接和没有链接2种(这个到UDP与connect可以找到相关内容)

没有链接的UDP不能调用getpeername,但是可以调用getsockname,和TCP一样,他的地址和端口不是在调用socket就指定了,而是在第一次调用sendto函数以后

已经链接的UDP,在调用connect以后,这2个函数都是可以用的(同样,getpeername也没太大意义。如果你不知道对方的地址和端口,不可能会调用connect)。

getsockname与getpeername用法与区别相关推荐

  1. @ini_get php,php中get_cfg_var()和ini_get()的用法及区别_php技巧_脚本之家

    本文实例讲述了php中get_cfg_var()和ini_get()的用法及区别.分享给大家供大家参考.具体分析如下: php里get_cfg_var()和ini_get()都是取得配置值的函数,当你 ...

  2. return true Java_[Java教程]js中return,return true,return false的用法及区别

    [Java教程]js中return,return true,return false的用法及区别 0 2015-11-16 23:00:03 1.语法及返回方式 ①返回控制与函数结果 语法为:retu ...

  3. 【Java学习笔记之二十九】Java中的equals和==的用法及区别

    Java中的"equals"和"=="的用法及区别 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String(&quo ...

  4. python ord()与chr()用法以及区别

    python ord()与chr()用法以及区别 原文:http://blog.csdn.net/yulock/article/details/52904035 ord()函数主要用来返回对应字符的a ...

  5. matlab ezplot fplot,【转】Matlab plot fplot ezplot用法与区别

    [转]Matlab plot fplot ezplot用法与区别 (2012-04-19 20:26:00) 标签: matlab fplot ezplot 数学函数 曲线 杂谈 函数plot 是绘制 ...

  6. TF:tensorflow框架中常用函数介绍—tf.Variable()和tf.get_variable()用法及其区别

    TF:tensorflow框架中常用函数介绍-tf.Variable()和tf.get_variable()用法及其区别 目录 tensorflow框架 tensorflow.Variable()函数 ...

  7. Spring中@Resource与@Autowired、@Qualifier的用法与区别

    Spring中@Resource与@Autowired.@Qualifier的用法与区别 1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法 ...

  8. break与continue的的用法以及区别

    /* break与continue的的用法以及区别 1. 当它们用在循环语句的循环体时,break用于立即退出本层循环,而continue仅仅结束本次循环(本次循环体内不执行 continue语句后的 ...

  9. typedef和#define的用法与区别

    typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: ...

最新文章

  1. 3 vue 线条箭头_教程|PPT绘制箭头最全攻略,收藏一下!
  2. Rainmeter 天气
  3. 纪念一下我2020年的努力结果,腾讯云社区创作总结
  4. VS Code 1.40 发布!可自行搭建 Web 版 VS Code!
  5. 堆栈溢出回答了我们不知道的Java首要问题
  6. Leetcode刷题(5)最长公共前缀
  7. 【UWP】批量修改图标尺寸
  8. .net流行面试试题(基础但重要)
  9. 虚拟机linux启动是来宾账户,配置Openstack Nova以自动启动在主机重新引导之前运行的guest虚拟机...
  10. Android 第三方SDK特征的收集
  11. Matlab窄带信号的测向算法
  12. 阿里国际站P4P直通车玩法
  13. CPU,缓存,内存,外存概念挖掘
  14. 小S坐月子的方法,难怪她身材那么好!
  15. android x86 uefi 安装教程,如何在Hyper-V上安装android-x86系统
  16. 黑鲨会升级鸿蒙吗,黑鲨游戏手机2系统更新好吗?
  17. 周志华----机器学习2
  18. laravel中guard是什么
  19. layui 设置table单元格背景色
  20. android+仿ios画廊,安卓仿ios14主题app

热门文章

  1. 数据库-优化-通过执行计划查询分析SQL执行计划-每个字段的说明
  2. spring整合junit测试
  3. jconsole工具检测堆内存变化
  4. Oracle之索引和索引碎片问题解决
  5. 云服务器维护人员,云服务器维护工作难吗
  6. 串口怎样配置才能无论奇偶校验都能正常接收_(七)串口(串行)通信
  7. redis(18)--发布和订阅
  8. 使用pip install出现超时警告的解决方法
  9. spark中的广播变量broadcast
  10. 去掉登陆下的“扫一扫,访问微社区