日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

getsockname与getpeername

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 "/programe/net/head.h"
#include "stdio.h"
#include "stdlib.h"

int main(int argc, char ** argu) {
int listenfd;
struct sockaddr_in servaddr;
pid_t pid;
char temp[100];
int n = 0;

listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(atoi(argu[1]));
bind(listenfd, (struct socket_addr *)&servaddr, sizeof(servaddr));
listen(listenfd, n);
for(;;) {
struct sockaddr_in local;
int connfd = accept(listenfd, (struct sockaddr *)NULL, NULL);
if((pid = fork()) == 0) {
struct sockaddr_in serv, guest;
char serv_ip[20];
char guest_ip[20];
int serv_len = sizeof(serv);
int guest_len = sizeof(guest);
getsockname(connfd, (struct sockaddr *)&serv, &serv_len);
getpeername(connfd, (struct sockaddr *)&guest, &guest_len);
inet_ntop(AF_INET, &serv.sin_addr, serv_ip, sizeof(serv_ip));
inet_ntop(AF_INET, &guest.sin_addr, guest_ip, sizeof(guest_ip));
printf("host %s:%d guest %s:%d\n", serv_ip, ntohs(serv.sin_port), guest_ip, ntohs(guest.sin_port));
char buf[] = "hello world";
write(connfd, buf, strlen(buf));
close(connfd);
exit(0);
}
close(connfd);
}
}

[root@liumengli net]# cat client1.c
#include "/programe/net/head.h"
#include "stdio.h"
#include "stdlib.h"

int main(int argc, char ** argv) {
int sockfd, n;
int my;
char buf[100];
struct sockaddr_in servaddr;

if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("create socket error\n");
exit(1);
}


bzero(&servaddr, sizeof(struct sockaddr_in));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));

if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0) {
printf("inet_pton error\n");
exit(1);
}


if((my = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) < 0) {
printf("connect error\n");
exit(1);
}

struct sockaddr_in serv, guest;
int serv_len = sizeof(serv);
int guest_len = sizeof(guest);
char serv_ip[20], guest_ip[20];

getsockname(sockfd, (struct sockaddr *)&guest, &guest_len);
getpeername(sockfd, (struct sockaddr *)&serv, &serv_len);

inet_ntop(AF_INET, &guest.sin_addr, guest_ip, sizeof(guest_ip));
inet_ntop(AF_INET, &serv.sin_addr, serv_ip, sizeof(serv_ip));

printf("host %s:%d, guest %s:%d\n", serv_ip, ntohs(serv.sin_port), guest_ip, ntohs(guest.sin_port));

n = read(sockfd, buf, 100);
buf[n] = '\0';

printf("%s\n", buf);
getchar();
close(sockfd);
exit(0);
}

補充:getsockname和getpeername調度時機很重要,如果調用時機不對,則無法正確獲得地址和端口。

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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。