我正在寫簡單的服務器/客戶端,並試圖獲取客戶端IP地址並將其保存在服務器端以決定哪個客戶端應該進入關鍵部分。我GOOGLE了幾次,但無法找到合適的方式從襪子結構獲得IP地址。如何從c中的sock結構獲取ip地址?
我相信這是一種從服務器接受來自客戶端的請求後從sock結構中獲取IP的方式。更具體的服務器後的C執行
csock = accept(ssock, (struct sockaddr *)&client_addr, &clen)
感謝
我正在寫簡單的服務器/客戶端,並試圖獲取客戶端IP地址並將其保存在服務器端以決定哪個客戶端應該進入關鍵部分。我GOOGLE了幾次,但無法找到合適的方式從襪子結構獲得IP地址。如何從c中的sock結構獲取ip地址?
我相信這是一種從服務器接受來自客戶端的請求後從sock結構中獲取IP的方式。更具體的服務器後的C執行
csock = accept(ssock, (struct sockaddr *)&client_addr, &clen)
感謝
OK假設你使用的IPV4然後執行以下操作:
struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&client_addr;
struct in_addr ipAddr = pV4Addr->sin_addr;
如果你再要的IP地址爲一個字符串,然後做以下:
char str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN);
IPV6是很容易的,以及...
struct sockaddr_in6* pV6Addr = (struct sockaddr_in6*)&client_addr;
struct in6_addr ipAddr = pV6Addr->sin6_addr;
並獲得一個字符串幾乎是相同的IPV4
char str[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &ipAddr, str, INET6_ADDRSTRLEN);
你忘了將'str'緩衝區傳遞給'inet_ntop()'。而'sin_addr'是一個結構 - 必須使用'sin_addr.s_addr'。值得注意的是,IPv4地址以網絡字節順序存儲,並將其視爲十六進制數,因此需要使用'ntohl(pV4Addr-> sin_addr.s_addr)'。 – Dummy00001 2010-06-17 12:22:15
得分......你也錯過了我不使用小寫字母「in6_addr」;)在ntohl前面,我並不經常打擾,因爲我仍然可以進行平等檢查(提供的都是網絡順序),它會打破inet_ntop (不是嗎?)。 – Goz 2010-06-17 12:58:42
這個問題被標記爲C - 你不能在'struct sockaddr_in *'之類的類型中遺漏'struct'。此外,IPV4方法應該使用'struct in_addr'而不是'int'來存儲地址,類似於你所展示的IPV6方法。 – caf 2010-06-18 05:57:43
假設client_addr
是struct sockaddr_in
(這通常是這樣)。您可以從client_addr.sin_addr.s_addr
獲取IP地址(作爲32位無符號整數)。
可以這種方式轉換爲字符串:
printf("%d.%d.%d.%d\n",
int(client.sin_addr.s_addr&0xFF),
int((client.sin_addr.s_addr&0xFF00)>>8),
int((client.sin_addr.s_addr&0xFF0000)>>16),
int((client.sin_addr.s_addr&0xFF000000)>>24));
提取IP地址和端口號,更容易和正確的方法是:
printf("IP address is: %s\n", inet_ntoa(client_addr.sin_addr));
printf("port is: %d\n", (int) ntohs(client_addr.sin_port));
肥皂盒的接受的答案不會對所有體系結構都是正確的。請參閱Big and Little Endian。
只是在這裏告訴大家,被檢查的答案在很多方面都是非常糟糕的答案。請爲所有其他程序員的好處,請不要使用它。 – Omnifarious 2017-06-15 06:43:09