MFC基于select模型的套接字类之服务器(2)

来源:互联网 发布:属性数据分析 编辑:程序博客网 时间:2024/05/29 08:37

1.3 绑定套接字

通过bind()函数绑定套接字,该函数的格式为

int bind(SOCKET s, const struct sockaddr* name, int namelen);
其中,参数s表示要绑定的套接字;name是要绑定的套接字地址;namelenname的大小。如果绑定套接字成功,则返回值为0,否则返回SOCKET_ERROR

1.3.1 sockaddr_insockaddr

在前文中已经提到,bind()函数的第二个参数类型是sockaddr结构的指针,表示套接字的地址。但在实际使用中,使用sockaddr_in结构来代替sockaddr结构。

(1)sockaddr_in结构

sockaddr_in结构体的定义如下所示

struct sockaddr_in{   short sin_family;   unsigned short sin_port;   struct in_addr sin_addr;   char sin_zero[8];};
其中,sin_family表示地址族;sin_port表示服务的端口号;sin_addr表示IP地址;in_zero是字符数组,包含8个元素。

Create()函数中,使用如下代码对sockaddr_in结构的对象m_server_sockaddr进行配置:

m_server_sockaddr.sin_family = AF_INET;m_server_sockaddr.sin_port = htons(port);m_server_sockaddr.sin_addr.S_un.S_addr = INADDR_ANY;
其中,AF_INET表示IPv4地址族;变量portCreate()函数的参数,表示服务器监听的端口号,在sockaddr_in结构中的端口号必须使用网络字节序的方式进行存储。htons()函数的作用是把以主机字节序排列的变量port变为以网络字节序排列。sin_addrin_addr结构的变量,in_addr结构是一个联合(union),该联合的名称为S_unS_addrS_un的成员,类型为unsigned longINADDR_ANY的值是0x00000000,表示IP地址是任意值。

端口号:一台主机可以提供许多服务,例如Web服务、FTP服务等。可以通过端口号来区分不同的服务。由于该变量的类型是unsigned short,所以端口号的范围是0-65535。对于自定义的服务,其端口号应在2014-49151之间进行选择。

网络字节序和主机字节序:指定了在内存中保存数据的顺序。按照网络字节序保存的数据,内存的低地址保存数据的高字节位,内存的高地址保存数据的低字节位,也叫做“大头”(big-endian)。按照主机字节序保存的数据,内存的低地址保存数据的低字节位,内存的高地址保存数据的高字节位,也叫做“小头”(little-endianIP地址。对于4个字节的数据0x12345678,按照网络字节序保存,则内存中的值依次为0x120x34,0x56,0x78;按照主机字节序保存时,内存中的值依次为0x780x56,0x34,0x12

使用htons()函数可以将主机字节序保存的数据转换为网络字节序,该函数的参数为主机字节序的数据,返回值为网络字节序的数据。

in_addr结构:

成员变量sin_addr表示IP地址,该变量的类型是in_addr结构。in_addr结构的定义如下:

struct in_addr{union{  struct{    unsigned char s_b1, s_b2, s_b3, s_b4;}S_un_b;  struct{unsigned short s_w1, s_w2;  }S_un_w;  unsigned long S_addr;}S_un;};
(2)sockaddr_insockaddr的关系

sockaddr_insockaddr都是用来表示套接字属性。sockaddr结构的定义为

struct sockaddr{   ushort sa_family;   char sa_data[14];};
sockaddr结构的定义可以看出,该结构的大小是2+14=16个字节;sockaddr_in结构在“1.3.1 sockaddr_insockaddr”中提到,如果不算sin_zero变量,其大小为2+2+4=8个字节,所以要再添加长度为8个字节的sin_zero作为填充项,使得这两个结构的大小相同。因此,这两个结构在使用时可以互相转换。

1.4 监听套接字

使用listen()函数实现套接字的监听。该函数的格式为

int listen(SOCKET s, int backlog);
其中,参数s表示要监听的套接字,backlog表示等待连接的最大队列长度,如果有4个客户端同时向服务器发送请求,那么前3个连接会被放在等待处理的队列中,以便服务器依次接受它们的连接,而第4个连接将会报错。当服务器接受了某个客户端的连接后,这个连接请求就会从队列中删除。

listen(m_socket_listen, backlog);
其中,m_socket_listen是在“1.3绑定套接字”中绑定的套接字,backlogCreate()函数的参数,用于指定等待连接的最大数量。

原创粉丝点击