您现在的位置是:首页 >技术交流 >Linux - 第13节 - 网络编程套接字(二)网站首页技术交流
Linux - 第13节 - 网络编程套接字(二)
1.简单的TCP网络程序
bind函数:
bind函数是对套接字进行IP地址+port端口号的绑定。
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
参数:sockfd:绑定的文件的文件描述符。也就是我们创建套接字时获取到的文件描述符。
addr:网络相关的属性信息,包括协议家族、IP地址、端口号等。
addrlen:传入的addr结构体的长度。
返回值:
绑定成功返回0,绑定失败返回-1,同时错误码会被设置。
注:
1.使用bind函数需要包含<sys/types.h>和<sys/socket.h>头文件。
2.使用struct sockaddr类型需要包含<netinet/in.h>和<arpa/inet.h>头文件
struct sockaddr_in结构体:
在绑定时需要将网络相关的属性信息填充到一个结构体当中,然后将该结构体作为bind函数的第二个参数进行传入,这实际就是struct sockaddr_in结构体。struct sockaddr_in结构体中的成员变量如下:
sin_family:表示公共的协议家族字段。
sin_port:表示端口号,是一个16位的整数。
sin_addr:sin_addr结构体的s_addr成员表示IP地址,是一个32位的整数。注:
1.struct sockaddr_in结构体的 sin_port 端口号在填充的时候,需要使用htons函数将端口号转为大端格式,因为端口号将来是要通过网络发送给对方主机的。
2.struct sockaddr_in结构体的 sin_addr.s_addr IP地址在填充的时候,需要注意几点:
需要使用inet_addr函数将字符串风格的点分十进制IP地址转换成整型的四字节IP地址,inet_addr函数声明如下图所示,参数cp为字符串风格的点分十进制IP地址,返回整型的四字节IP地址。
这里inet_addr函数除了会将字符串风格的点分十进制IP地址转换成整型的四字节IP地址,还会自动将整型的四字节IP地址进行主机转网络,即返回的整型的四字节IP地址是大端的。
使用 inet_addr函数需要包含<sys/socket.h><netinet/in.h><arpa/inet.h>头文件。
服务器一般不关心会bind绑定哪一个IP地址,而是可以绑定任意的IP地址,那么我们直接给sin_addr.s_addr赋值INADDER_ANY即可,如下代码所示,该做法强烈推荐。如果给服务器绑定特定的IP地址,那么该服务器只能收到目的IP为该IP的数据,一般在做测试时使用。
INADDER_ANY是一个宏,其数值是0,数值0转不转大端是无所谓的,因此INADDER_ANY也可以不用调用htonl函数做主机转网络操作。
local.sin_addr.s_addr = ip_.empty() ? htonl(INADDR_ANY) : inet_addr(ip_.c_str());
云服务器有一些特殊情况:云服务器禁止bind绑定任何确定IP,因此只能使用INADDER_ANY初始化sin_addr.s_addr IP地址。3.struct sockaddr_in属于系统级的概念,不同的平台接口设计可能会有点差别。
struct sockaddr_in结构体初始化函数:
给struct sockaddr_in结构体填充内容之前最好先进行初始化,给struct sockaddr_in结构体初始化可以使用bzero函数或memset函数,下图一二是bzero函数和memset函数的函数声明,这里不再细讲。
注:使用bzero函数和memset函数需要包含<string.h>头文件。