getpeername、getsockname
函数原型:
#include<sys/socket.h>
int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);
int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);
函数功能:
getsockname函数用于获取与某个套接字关联的本地协议地址
getpeername函数用于获取与某个套接字关联的外地协议地址
返回值:
对于这两个函数,如果函数调用成功,则返回0,如果调用出错,则返回-1。
实例:
/***
client.c
***/
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h> #define PORT 6563 int main(int argc, char **argv)
{
struct sockaddr_in servaddr;
struct sockaddr_in clientaddr;
int sockfd;
int clientaddrlen = sizeof(clientaddr);
char ipAddress[INET_ADDRSTRLEN]; if (argc < )
{
printf("parameter error");
} sockfd = socket(AF_INET, SOCK_STREAM, );
memset(&servaddr, ,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT); if (inet_pton(AF_INET, argv[], &servaddr.sin_addr) <= )
{
printf("server address error\n");
} connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); getsockname(sockfd, (struct sockaddr*)&clientaddr, &clientaddrlen);
printf("client:clinet address = %s:%d\n",inet_ntop(AF_INET,
&clientaddr.sin_addr, ipAddress, sizeof(ipAddress)),
ntohs(clientaddr.sin_port));
return ;
}
/***
server.c
***/
#include<sys/socket.h>
#include<stdio.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h> #define MAXLINE 4096
#define PORT 6563
#define LISTENQ 1024 int main()
{
int listenfd, connfd;
struct sockaddr_in servaddr;
struct sockaddr_in listenAddr, connecteAddr, peerAddr;
int listenAddrlen, connectedAddrlen, perrLen; char ipAddr[INET_ADDRSTRLEN];
listenfd = socket(AF_INET, SOCK_STREAM, );
memset(&servaddr, ,sizeof(servaddr)); servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT); bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); listen(listenfd, LISTENQ);
listenAddrlen = sizeof(listenAddr);
getsockname(listenfd,(struct sockaddr *)&listenAddr,
&listenAddrlen);
printf("listen address = %s:%d\n",inet_ntoa(listenAddr.sin_addr),
ntohs(listenAddr.sin_port)); while()
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
connectedAddrlen = sizeof(connecteAddr);
getsockname(connfd, (struct sockaddr*)&connecteAddr, &connectedAddrlen);
printf("connected server address = %s:%d\n",inet_ntoa(connecteAddr.sin_addr),
ntohs(connecteAddr.sin_port)); getpeername(connfd, (struct sockaddr*)&peerAddr, &perrLen);
printf("connected peer address = %s:%d\n",inet_ntop(AF_INET,
&peerAddr.sin_addr, ipAddr, sizeof(ipAddr)),
ntohs(peerAddr.sin_port));
} return ;
}
运行结果:

从上面的代码中可以看到,服务器端listenfd套接字描述符对应的地址即为绑定的通配IP地址和指定的端口,而connfd套接字描述符对应的连接的服务器端的地址为内核赋予的地址和用户指定的端口。
上面的客户端与服务器端的代码中使用了函数inet_ntoa,inet_pton对32位的地址进行转换,其中inet_ntoa是较老的函数,与它一起的还有函数inet_addr和inet_ntoa,这三个函数的定义如下:
#include<arpa/inet.h>
int inet_aton(const char *strptr, struct in_addr *addrptr);
in_addr_t inet_addr(const char *strptr);
char *inet_ntoa(struct in_addr inaddr);
inet_aton与inet_addr函数的功能类似,都是将点分十进制的字符串表示的IP地址转换成32位的网络字节序的IPv4地址。
inet_ntoa函数将32位的网络字节序的IPv4地址转换成点分十进制的字符串表示的IP地址,inet_addr函数已被废弃,并且这三个函数只针对IPv4地址有效,在点分十进制数串和32位的网络字节序二进制值间进行转换,如果要对于IPv4和IPv6都适用,那么使用下面两个函数:
#include<arpa/inet.h>
int inet_pton(int family, const char *strptr, void *addrptr);
const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);
函数中的p和n分别代表表达式(presentation)和数值(numeric)
所以inet_pton函数将strptr指针所指的字符串转换为网络地址(IPv4和IPv6),再将地址保存到addrptr指向的结构体中,inet_ntop将网络地址转为字符串表示的地址,结果存放在strptr中,len参数是strptr的大小。
这两个函数支持IPv4和IPv6,所以需要通过参数family来指定,当前要转换的是IPv4地址还是IPv6地址。
getpeername、getsockname的更多相关文章
- WinSock基本知识
这里不打算系统地介绍socket或者WinSock的知识.首先介绍WinSock API函数,讲解阻塞/非阻塞的概念:然后介绍socket的使用. WinSock API Socket接口是网络编程( ...
- 关于 getsockname、getpeername和gethostname、gethostbyname
一.gethostname,gethostbyname的用法 这两个函数可以用来获取主机的信息.gethostname:获取主机的名字gethostbyname:通过名字获取其他的信息(比如ip) 1 ...
- Python_socket常见的方法、网络编程的安全注意事项、socketsever模块、浏览器中在一段时间记录用户的登录验证机制
1.socket常见的方法 socket_常见方法_服务器端 import socket from socket import SOL_SOCKET,SO_REUSEADDR sk = socket. ...
- python 网络编程
一.网络知识的一些介绍 socket是网络连接端点.例如当你的Web浏览器请求www.pythontik.com上的主页时,你的Web浏览器创建一个socket并命令它去连接www.pythontik ...
- python之socket
一.初识socket socket 是网络连接端点,每个socket都被绑定到一个特定的IP地址和端口.IP地址是一个由4个数组成的序列,这4个数均是范围 0~255中的值(例如, ...
- UNIX网络编程-基本API介绍(二)
参考链接:http://www.cnblogs.com/riky/archive/2006/11/24/570713.aspx 1.getsockname和getpeername getsocknam ...
- UNIX网络编程-基本API介绍(一)
1.基本结构 大多数套接口函数都需要一个指向套接口地址结构的指针作为参数.每个协议族都定义它自己的套接口地址结构.这些结构的名字均以“sockaddr_”开头,并以对应每个协议族的唯一后缀结束. 1. ...
- 网络IPC:套接字之寻址
在学习用套接字做一些有意义的事情之前,需要知道如何确定一个目标通信进程. 进程的标识有两个部分:计算机的网络地址可以帮助标识网络上想与之通信的计算机,而服务可以帮助标识计算机上特定的进程. 1.字节序 ...
- 《unix网络编程》笔记
inet_pton和inetntop函数.字母p和n代表presentation和numeric.地址的表达presentation格式通常是ASCIL串,数值(numeric)格式则是存在于套接字地 ...
随机推荐
- GNU Makefile中的条件控制结构
在常见的编程语言中,使用条件控制结构诸如if ... else if ... else...是很寻常的事情,那么在GNU Makefile中如何使用呢? ifeq ifneq 例如:foo.sh #! ...
- Sitecore个性化 - 什么是历史个性化?
顾名思义,Sitecore中的历史个性化允许您根据访问者过去在您网站上的行为来设置个性化规则. 许多组织选择Sitecore 作为其高级个性化功能的网站平台 - 历史个性化只是一种方法. 查看我们关 ...
- Docker File
- Redis(四)Pub/Sub
发布与订阅 Pub/Sub模式应该非常熟悉,在现实应用中被广泛的使用.如:微博中关注某个号,这个号有发新博时,关注的都会收到:github上watch了某个项目,当有issue时,就会发邮件. Red ...
- http内网转发
package main import ( "io" "log" "net/http" "strings" ) func ...
- 【java】java反射获取属性和属性值,java反射设置属性和属性值
今日份代码如下: /** * * @Author: SXD * @Description: * @Date: create in 2019/9/20 15:39 */ public class Pro ...
- 深入V8引擎-初始化默认Platform
本来寻思着写一篇"'Hello' + ', World'"是怎么从JS代码编译然后输出的,然而compile过程的复杂性远超我的想象,强上怕会走火入魔,还是老老实实先回家种田,找点 ...
- pip 命令安装 rdbtools
命令 pip install tdbtools 如果出现类似如下错误 Could not fetch URL https://pypi.org/simple/redis/ 说明morning的pip ...
- Linux纯小白操作(以安装JDK为例)
[本文只针对纯小白,有基础的请略过] 最近公司给分配工作使用的虚拟机都是Linux系统的,以前完全没接触过,今天按照网上一些教程操作,好多地方感觉对小白不够友好(有些问题非常小白那些教程没有写出来.我 ...
- nginx配置多个TLS证书,以及TLS SNI简介
背景 原来申请的正式域名备案通过,TLS证书也申请了.之前使用的临时域名和证书作为测试环境使用.于是要在单个ECS主机上配置nginx多个证书和多个域名. 实践 nginx部署多个TLS证书很简单,在 ...