Crazy knowledge base

套接字(Socket)【概念和套接字地址】

什么是Socket?其实我并没有看到过具体的文字解释,至少我手里的书没有写,不过根据我个人的理解,举一个例子:Lewis跟Nico两人聊QQ,QQ是一个独立的应用程序,那么它对应了两个Socket,一个在Lewis的电脑上,一个在Nico的电脑上。当Lewis对Nico说:”周末我们去开卡丁车吧!“,这句话就是一段数据,这段数据会先储存在Lewis电脑Socket上,我们在”分层网络模型“一文中提到过,TCP存在于传输层,同时,我们在”端口、IP协议“一文中又提到了TCP传输过程(三次握手建立连接,三次握手关闭连接),当Lewis的QQ和Nico的QQ连接成功后,Lewis的Socket将这段话的数据发送到Nico的电脑中,但是Nico暂时还没看到,因为数据会先存放在Nico电脑的Socket当中,然后Socket会把数据呈现给Nico看。

到了这里不禁要问,数据传送过程中为什么要多出Socket这样东西?答:因为不同的应用程序对应不同的Socket,而Socket保证了QQ的数据不会到处乱跑,不会一冲动跑到MSN上去了。因为QQ和MSN两个应用程序的Socket内容是完全不同的。那么Socket里面到底是什么?答:Socket套接字地址!

套接字地址是一个数据结构,我们仅基于TCP传输协议作为例子。套接字地址这个数据结构里面包含了:地址类型、端口号、IP地址、填充字节这4种数据。而它的数据结构原型为:

#include 
 
struct sockaddr_in{
     unsigned short         sin_family;     /*地址类型*/
     unsigned short int     sin_port;       /*端口号*/
     struct in_addr         sin_addr;       /*IP地址*/
     unsigned char          sin_zero[8];    /*填充字节,一般赋值为0*/
};

其中:

sin_family表示地址类型,对于基于TCP/IP传输协议的通信,该值只能是AF_INET;
sin_prot表示端口号,例如:21 或者 80 或者 27015,总之在0 ~ 65535之间;
sin_addr表示32位的IP地址,例如:192.168.1.5 或 202.96.134.133;
sin_zero表示填充字节,一般情况下该值为0;
Socket数据的赋值实例:

struct sockaddr_in Lewis;
Lewis.sin_family      = AF_INET;
Lewis.sin_port        = htons(80);
Lewis.sin_addr.s_addr = inet_addr("202.96.134.133");
memset(Lewis.sin_zero,0,sizeof(Lewis.sin_zero));

分析:我们设置了一个名叫Lewis的套接字地址,它基于TCP/IP协议,因此sin_family的值为AF_INET,这个是雷打不动的,只要使用TCP/IP协议簇,该值就是AF_INET;htons是端口函数,以后介绍,这就表示设置了端口号为80;sin_addr是一个数据结构,原型是:

struct in_addr{
     unsigned long     s_addr;
};

因此,Lewis这个套接字地址的IP赋值格式是Lewis.sin_addr.s_addr,inet_addr函数也是日后再说,这里表示设置IP地址为202.96.134.133;而memset函数在这里起到给sin_zero数组清零的作用,它的原型是:

memset(void *s, int c, size_t n);
/*函数表示,将s指向内存区域中前n个字节,并赋上c的值*/
套接字(Socket)【概念和套接字地址】
滚动到顶部