socket程式設計之獲取客戶端和服務端ip

2021-09-03 06:31:13 字數 3146 閱讀 9791

getsockname函式用於獲取與某個套接字關聯的本地協議位址 

getpeername函式用於獲取與某個套接字關聯的外地協議位址

定義如下:

#include

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

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

對於這兩個函式,如果函式呼叫成功,則返回0,如果呼叫出錯,則返回-1。

使用這兩個函式,我們可以通過套接字描述符來獲取自己的ip位址和連線對端的ip位址,如在未呼叫bind函式的tcp客戶端程式上,可以通過呼叫getsockname()函式獲取由核心賦予該連線的本地ip位址和本地埠號,還可以在tcp的伺服器端accept成功後,通過getpeername()函式來獲取當前連線的客戶端的ip位址和埠號。

2.1 服務端示例

#define maxline 4096

#define port 6563

#define listenq 1024

#define buffer_size 4096

#include#include#include#include#include#include#include#include#includeint main()

memset(&servaddr, 0, sizeof(servaddr));

servaddr.sin_family = af_inet;

servaddr.sin_addr.s_addr = htonl(inaddr_any);

servaddr.sin_port = htons(port);

if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1 )

if( listen(listenfd, listenq) == -1)

listendaddrlen = sizeof(listendaddr);

//獲取監聽的位址和埠

if(getsockname(listenfd, (struct sockaddr *)&listendaddr, &listendaddrlen) == -1)

printf("listen address = %s:%d\n", inet_ntoa(listendaddr.sin_addr), ntohs(listendaddr.sin_port));

printf("*****=waiting for client's request*****=\n");

while(1)

//獲取connfd表示的連線上的本地位址

connectedaddrlen = sizeof(connectedaddr);

if(getsockname(connfd, (struct sockaddr *)&connectedaddr, &connectedaddrlen) == -1)

printf("connected server address = %s:%d\n", inet_ntoa(connectedaddr.sin_addr), ntohs(connectedaddr.sin_port));

//獲取connfd表示的連線上的對端位址

peerlen = sizeof(peeraddr);

if(getpeername(connfd, (struct sockaddr *)&peeraddr, &peerlen) == -1)

printf("connected peer address = %s:%d\n", inet_ntop(af_inet, &peeraddr.sin_addr, ipaddr, sizeof(ipaddr)), ntohs(peeraddr.sin_port));

n = recv(connfd, buff, maxline, 0);

buff[n] = '\0';

printf("recv msg from client: %s\n", buff);

close(connfd);

}close(listenfd);

return 0;

}

2.2 客戶端示例

#define port 6563

#define send_size 4096

#include#include#include#include#include#include#include#include#includeint main(int argc, char **argv)

if( (sockfd = socket(af_inet, sock_stream, 0)) < 0 )

memset(&servaddr, 0, sizeof(servaddr));

servaddr.sin_family = af_inet;

servaddr.sin_port = htons(port);

if(inet_pton(af_inet, argv[1], &servaddr.sin_addr) <= 0)

//向伺服器端發起連線請求

if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 )

//獲取sockfd表示的連線上的本地位址

if(getsockname(sockfd, (struct sockaddr*)&clientaddr, &clientaddrlen) == -1 )

printf("client:client ddress = %s:%d\n", inet_ntop(af_inet, &clientaddr.sin_addr, ipaddress, sizeof(ipaddress)), ntohs(clientaddr.sin_port));

printf("send msg to server: \n");

fgets(sendline, 4096, stdin);

if(send(sockfd, sendline, strlen(sendline), 0) < 0)

close(sockfd);

return 0;

}

本文主要參考:

SOCKET客戶端程式設計

1.建立socket物件 socket建構函式有4個引數,第乙個是family,代表位址家族af net,af net6等,第二個是type,套接字型別sock stream 流套接字 和sock dgram 資料報套接字 import socket s socket.socket socket.a...

socket程式設計範本 客戶端

include include void main if lobyte wsadata.wversion 1 hibyte wsadata.wversion 1 socket sockclient socket af inet,sock stream,0 建立套接字 socket sockaddr ...

socket程式設計 TCP IP 多客戶端

支援多客戶的client server程式 前面的client server程式只能實現server和乙個客戶的對話。在實際應用中,往往是在伺服器上執行乙個永久的程式,它可以接收來自其他多個客戶端的請求,提供相應的服務。為了實現在伺服器方給多個客戶提供服務的功能,需要對上 面的程式進行改造,利用多執...