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

1.3 绑定套接字

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

int bind(SOCKET s, const struct sockaddr* name, int namelen);
其中,参数s 表示要绑定的套接字; name 是要绑定的套接字地址; namelen name 的大小。如果绑定套接字成功,则返回值为 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 地址族;变量 port Create() 函数的参数,表示服务器监听的端口号,在 sockaddr_in 结构中的端口号必须使用网络字节序的方式进行存储。 htons() 函数的作用是把以主机字节序排列的变量 port 变为以网络字节序排列。 sin_addr in_addr 结构的变量, in_addr 结构是一个联合( union ),该联合的名称为 S_un S_addr S_un 的成员,类型为 unsigned long INADDR_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_in sockaddr 的关系

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

struct sockaddr{
   ushort sa_family;
   char sa_data[14];
};
sockaddr 结构的定义可以看出,该结构的大小是 2+14=16 个字节; sockaddr_in 结构在“1.3.1 sockaddr_in sockaddr ”中提到,如果不算 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 绑定套接字”中绑定的套接字, backlog Create() 函数的参数,用于指定等待连接的最大数量。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值