在网路编程中, 我们经常听说到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) 这些基本的概念了。