在网路编程中, 我们经常听说到socket, 今天, 我们来详细了解一下socket的name. 一个socket name有三要素, 以WinSock为例, 它是在结构体SOCKADDR_IN中定义的, 三要素就是: 协议, ip, port.
下面, 我们以生宝宝并取名的过程来叙述。对应关系为
socket ------ 宝宝
name ------ 名字
bind ----- 给宝宝命名
socket name(也可以说是socket地址吧) ------ 宝宝的名字
好, 该看程序了(如下程序是对tcp服务端程序的裁剪):
#include <stdio.h> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") /**************************************************************** socket ------ 宝宝 name ------ 名字 bind ----- 给宝宝命名 socket name(也可以说是socket地址吧) ------ 宝宝的名字 ****************************************************************/ int main() { // 网络初始化 (生孩子前做准备工作) WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); WSAStartup( wVersionRequested, &wsaData); // 创建socket, 此时socket没name (生了一个孩子, 但是还买来得及给孩子命名) SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); // 查看socket name (亲朋好友来问孩子叫什么名字, 最终发现还没取名, 所以只能叫通用的"宝宝": {0, 0.0.0.0, 0} ) { SOCKADDR_IN addrMy; memset(&addrMy, 0, sizeof(addrMy)); int len = sizeof(addrMy); getsockname(sockSrv, (sockaddr*)&addrMy, &len); printf("%d\n", addrMy.sin_family); // 0 printf("%s\n", inet_ntoa(addrMy.sin_addr)); // 0.0.0.0 printf("%d\n", ntohs(addrMy.sin_port)); // 0 } // 定义一个name, 也可以说是地址 (费劲心思, 想到一个可以给宝宝的名字: {AF_INET, 192.168.1.100, 8888} ) SOCKADDR_IN addrSrv; addrSrv.sin_family = AF_INET; addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.100"); addrSrv.sin_port = htons(8888); // 将socket与定义的name绑定起来 (正式为宝宝取一个刚才费劲心思想好的名字) bind(sockSrv,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); // 再次查看socket的name (亲朋好友再次来关心地问宝宝叫什么名字, 并从此将宝宝与这个名字挂钩了) { SOCKADDR_IN addrMy; memset(&addrMy, 0, sizeof(addrMy)); int len = sizeof(addrMy); getsockname(sockSrv, (sockaddr*)&addrMy, &len); printf("%d\n", addrMy.sin_family); // 2 printf("%s\n", inet_ntoa(addrMy.sin_addr)); // 192.168.1.100 printf("%d\n", ntohs(addrMy.sin_port)); // 8888 } // 后续过程我就不说了 // ...... return 0; }结果为:
0
0.0.0.0
0
2
192.168.1.100
8888
好了, 通过本文, 我们更加清楚了socket, name, bind, socket name(socket address) 这些基本的概念了。