getsockname和getpeername测试
生活随笔
收集整理的這篇文章主要介紹了
getsockname和getpeername测试
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在兩臺計算機上建立一個網絡連接,需要五個要素:本機地址、本機端口、協議類型、遠端端口、遠端地址,那么如何從一個建立好的連接上獲取這些信息呢?就需要用到
? ? getsockname和getpeername這兩個函數。
但前提是要在建立好的連接上。
作為客戶端,要在正確調用connect()之后,才能使用這兩個函數
作為服務端,要在正確調用accept()之后,才能使用這兩個函數
以下為測試代碼,windows/linux下均可編譯運行。
#include <stdint.h> #include <stdio.h> #include <memory.h>#ifdef WIN32 #include <windows.h> typedef int32_t socklen_t; #define close(x) closesocket(x) #else #include <errno.h> #include <arpa/inet.h> #include <unistd.h> #define INVALID_SOCKET (-1) typedef int32_t SOCKET; #endifint32_t Errno() { #ifdef WIN32return WSAGetLastError(); #elsereturn errno; #endif }void test_getname(SOCKET sock, const char *desc) {printf("%s\n", desc);struct sockaddr_in addr;socklen_t addr_len = sizeof(addr);int32_t ret = getsockname(sock, (struct sockaddr *)&addr, &addr_len);if (ret == 0) {printf("getsockname succ:%s:%d\n", inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));} else {printf("getsockname failed, error = %d\n", Errno());}memset(&addr, 0, sizeof(addr));ret = getpeername(sock, (struct sockaddr *)&addr, &addr_len);if (ret == 0) {printf("getpeername succ:%s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));} else {printf("getpeername failed,error = %d\n", Errno());} }void test_connect() {sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("127.0.0.1");addr.sin_port = htons(5000);SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);test_getname(sock, "before connect");inet32_t ret = connect(sock, (sockaddr *)&addr, sizeof(addr));if (ret != 0) {printf("connect error, errno: %d\n", Errno());return;}test_getname(sock, "after connect");close(sock); }void test_accept() {SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (INVALID_SOCKET == sock) {printf("create socket error, errno = %d\n", Errno());return;}sockaddr_in srvAddr;memset(&srvAddr, 0, sizeof(srvAddr));srvAddr.sin_family = AF_INET;srvAddr.sin_addr.s_addr = htonl(INADDR_ANY);srvAddr.sin_port = htons(5000);test_getname(sock, "before bind");int32_t ret = bind(sock, (sockaddr *)&srvAddr, sizeof(srvAddr));printf("bind:%s:%d\n", inet_ntoa(srvAddr.sin_addr), ntohs(srvAddr.sin_port));test_getname(sock, "after bind");if (ret != 0) {printf("bind listen socket error, errno = %d\n", Errno());return;}ret = listen(sock, SOMAXCONN);if (ret != 0) {return;}sockaddr_in cliAddr;socklen_t cliAddrLen = sizeof(cliAddr);SOCKET new_sock = accept(sock, (sockaddr *)&cliAddr, &cliAddrLen);printf("accept:%s:%d\n", inet_ntos(cliAddr.sin_addr), ntohs(cliAddr.sin_port));test_getname(new_sock, "after_accept");close(sock);close(new_sock); }int32_t main() { #ifdef WIN32WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData); #endif//test_connect();test_accept(); #ifdef WIN32WSACleanup(); #endifgetchar();return 0; }? 測試結果:
? ?connect:
before connect getsockname failed,error=10022 getpeername failed,error=10057 after connect getsockname succ:127.0.0.1:4618 getpeername succ:127.0.0.1:5000? ?accept:
before bind getsockname failed,error=10022 getpeername failed,error=10057 bind:0.0.0.0:5000 after bind getsockname succ:0.0.0.0:5000 getpeername failed,error=10057 accept:127.0.0.1:4630 after accept getsockname succ:127.0.0.1:5000 getpeername succ:127.0.0.1:4630總結
以上是生活随笔為你收集整理的getsockname和getpeername测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: getsockopt和setsockop
- 下一篇: 使用gethostname()函数和ge