服务端视角的C++从入门到精通(十六)

230 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情

socket网络通信中的一些小知识之二

上篇文章讲到在Linux系统中进行socket编程时需要完成的第一步就是创建一个socket。

创建的socket_fd这个整型数的分配就是从0开始按顺序分的,如果已经被占用则去看下一个号有没有被占用。

第二步

int port = 8888;
struct sockaddr_in svr_addr;
svr_addr.sin_family = AF_INET;
svr_addr.sin_port = htons(port);
svr_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&(svr_addr.sin_zero), 8);
if (bind(sock_fd, (struct sockaddr*)&svr_addr, sizeof(struct sockaddr)) < 0) {
  fprintf(stderr, "connection bind error!");
}

sockaddr_in是和socket通信有关的一个结构体,里面包含了socket通信所需要的信息。比如sin_family,就是和第一步创建socket时传的协议簇参数一致。又比如sin_port就是端口号,这里涉及到不同主机之间数据的组织方式的区别,也就是大/小端的区别。简单来说,大端就是字节存放到内存的地址,而小端则是字节存放到内存的地址,就比如1这个整型数,假定内存地址增长方向和我们人类的阅读方向相反,也就是从左到右依次减小(但这其实与人类对数字高/低位的认知是一致的),则在32位大端CPU系统中存储方式就是0x01000000,而在小端CPU系统中则是0x00000001。所以,简言之,就是符合我们人类阅读习惯的,就是端,这也的确是大部分厂商采用的主机字节序,只有IBM、摩托罗拉、惠普,以及一些单片机采用大端存储。而我们之所以这里在设置网络地址时要进行转换,也是因为我们现在假定我们使用的Linux是使用的intel的x86、x64处理器芯片,而网络序(也就是数据在网络上的排布顺序)则是典型的的端序,所以我们需要使用htonl这一函数实现h(ost)到n(etwork)的转换,而l则代表long,长整型,s则代表short,短整型。INADDR_ANY则是代表0.0.0.0这一网络地址。