getsockname与getpeername用法与区别
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用法与区别相关推荐
- @ini_get php,php中get_cfg_var()和ini_get()的用法及区别_php技巧_脚本之家
本文实例讲述了php中get_cfg_var()和ini_get()的用法及区别.分享给大家供大家参考.具体分析如下: php里get_cfg_var()和ini_get()都是取得配置值的函数,当你 ...
- 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 ...
- 【Java学习笔记之二十九】Java中的equals和==的用法及区别
Java中的"equals"和"=="的用法及区别 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String(&quo ...
- python ord()与chr()用法以及区别
python ord()与chr()用法以及区别 原文:http://blog.csdn.net/yulock/article/details/52904035 ord()函数主要用来返回对应字符的a ...
- matlab ezplot fplot,【转】Matlab plot fplot ezplot用法与区别
[转]Matlab plot fplot ezplot用法与区别 (2012-04-19 20:26:00) 标签: matlab fplot ezplot 数学函数 曲线 杂谈 函数plot 是绘制 ...
- TF:tensorflow框架中常用函数介绍—tf.Variable()和tf.get_variable()用法及其区别
TF:tensorflow框架中常用函数介绍-tf.Variable()和tf.get_variable()用法及其区别 目录 tensorflow框架 tensorflow.Variable()函数 ...
- Spring中@Resource与@Autowired、@Qualifier的用法与区别
Spring中@Resource与@Autowired.@Qualifier的用法与区别 1.@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法 ...
- break与continue的的用法以及区别
/* break与continue的的用法以及区别 1. 当它们用在循环语句的循环体时,break用于立即退出本层循环,而continue仅仅结束本次循环(本次循环体内不执行 continue语句后的 ...
- typedef和#define的用法与区别
typedef和#define的用法与区别 一.typedef的用法 在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像: ...
最新文章
- 3 vue 线条箭头_教程|PPT绘制箭头最全攻略,收藏一下!
- Rainmeter 天气
- 纪念一下我2020年的努力结果,腾讯云社区创作总结
- VS Code 1.40 发布!可自行搭建 Web 版 VS Code!
- 堆栈溢出回答了我们不知道的Java首要问题
- Leetcode刷题(5)最长公共前缀
- 【UWP】批量修改图标尺寸
- .net流行面试试题(基础但重要)
- 虚拟机linux启动是来宾账户,配置Openstack Nova以自动启动在主机重新引导之前运行的guest虚拟机...
- Android 第三方SDK特征的收集
- Matlab窄带信号的测向算法
- 阿里国际站P4P直通车玩法
- CPU,缓存,内存,外存概念挖掘
- 小S坐月子的方法,难怪她身材那么好!
- android x86 uefi 安装教程,如何在Hyper-V上安装android-x86系统
- 黑鲨会升级鸿蒙吗,黑鲨游戏手机2系统更新好吗?
- 周志华----机器学习2
- laravel中guard是什么
- layui 设置table单元格背景色
- android+仿ios画廊,安卓仿ios14主题app