目录
- 主机字节序/小端字节序:整数的高位字节存储在内存的高地址处,低位字节存储在内存的低地址处
- 网络字节序/大端字节序:整数的高位字节存储在内存的底地址处,低位字节存储在内存的高地址处
检查你自己机器的字节序?
其中 test.value1 = 0x0102 可以这么看:
short是2个字节的。0x表示之后是十六进制,一个十六进制数字需要四个二进制数字表示,一个二进制数字是1bit,所以0102四个数字一共是4*4=16bit也就是二字节,两个十六进制数字占一个字节。所以test.value2中存放了(十六进制的)01和02。
字节序转化函数(主机字节序与网络字节序互换)
#include <arpa/inet.h>
//host to net long 32 bit
uint32_t htonl(uint32_t hostlong);
uint32_t ntohl(uint32_t netlong);
//net to host short 16bit
uint16_t htons(uint16_t hostshort);
uint16_t ntohs(uint16_t netshort);
IP地址转换函数(IP地址与整数互换)
通常我们使用点分十进制来表示IP地址,但编程中我们需要把它们转化为整数才能使用,而记录日志时则相反,我们需要把整数表示的IP地址转化为点分十进制。
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/*
用于将点分十进制表示的IPv4地址转化为网络字节序整数表示的地址
*/
in_addr_t inet_addr(const char *str);
/*
用于转换整数表示的网络字节排序地址为点分十进制的字符串。
该字符串的空间为静态分配的,这意味着第二次调用该函数时,
上一次调用将会被重写(覆盖)。
*/
char *inet_ntoa(struct in_addr in);
Socket
Linux中的网络编程通过Socket(套接字)接口实现,Socket是一种文件描述符
- 流式套接字(SOCK_STREAM)
定义一种可以提供可靠的、面向连 接的通讯流,它使用了TCP协议。
- 数据报套接字(SOCK_DGRAM)
定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的不保证可靠,无差错,UDP协议
- 原始套接字
原始套接字允许对低层协议如IP或ICMP直接访问,主要用于新的网络协议的测试等。
TCP/IP专用socket结构体
创建socket——socket()
绑定socket——bind()
服务器就绑服务器自己的的IP地址(众所周知的)端口信息,客户端就绑自己的IP地址端口信息,但一般客户端不bind
bind函数并不是总是需要调用的,只有用户进程想与一个具体的地址或端口相关联的时候才需要调用这个函数。如果用户进程没有这个需要,那么程序可以依赖内核的自动的选址机制来完成自动地址选择,而不需要调用bind的函数,同时也避免不必要的复杂度。在一般情况下,对于服务器进程问题需要调用bind函数,对于客户进程则不需要调用bind函数。
监听socket——listen()
backlog一般写4
接受socket——accept()
发起连接——connect()
关闭连接——close()
数据读写
TCP数据读写
UDP数据读写
通信模型
TCP通信模型
主要的步骤:(服务器端)
1. 创建一个socket,用函数socket()
2. 绑定IP地址、端口等信息到socket上,用函数bind()
3.设置允许的最大连接数,用函数listen()
4.接收客户端上来的连接,用函数accept()
5.收发数据,用函数send()和recv(),或者read()和write()
6.关闭网络连接
UDP通信模型
服务器模型
在网络程序里面,一般来说都是许多客户对应一个服务器,为了处理客户的请求, 对服务端的程序就提出了特殊的要求。目前最常用的服务器模型有:
- 循环服务器:服务器在同一个时刻只可以响应一个客户端的请求
- 并发服务器:服务器在同一个时刻可以响应多个客户端的请求
TCP循环服务器
TCP服务器接受一个客户端的连接,然后处理,完成了这个客户的所有请求后,断开连接。算法如下:
TCP循环服务器一次只能处理一个客户端的请求。只有在这个客户的所有请求都满足后, 服务器才可以继续后面的请求。这样如果有一个客户端占住服务器不放时,其它的客户机都不能工作了,因此,TCP服务器一般很少用循环服务器模型的
UDP循环服务器
UDP循环服务器的实现方法:UDP服务器每次从套接字上读取一个客户端的请求->处理->然后将结果返回给客户机
因为UDP是非面向连接的,没有一个客户端可以老是占住服务端, 服务器对于每一个客户机的请求总是能够满足
TCP并发服务器
TCP并发服务器可以解决TCP循环服务器客户机独占服务器的情况。但同时也带来了问题:为了响应客户的请求,服务器要创建子进程来处理,而创建子进程是一种非常消耗资源的操作
多路复用I/O(防阻塞)
阻塞函数在完成其指定的任务以前不允许程序继续向下执行.例如:当服务器运行到accept语句时,而没有客户请求连接,服务器就会停止在accept语句上等待连接请求的到来.这种情况称为阻塞(blocking),而非阻塞操作则可以立即完成。例如,如果你希望服务器仅仅检查是否有客户在等待连接,有就接受连接,否则就继续做其他事情,则可以通过使用select系统调用来实现.除此之外,select还可以同时监视多个套接字
网络连接改为“桥接模式”,来ping通其他人
注意:如果光ping通其他人,可能服务器客户端还是运行不了,要试着做一下下面两步才行。
步骤一
vmware 桥接模式下与虚拟机互ping不通问题-终极解决办法(用方法二即可,改完如果不行重启一下虚拟机)
桥接模式的“桥接到”选项,选择以太网的话只能ping其他人,选择wifi只能ping外网。
步骤二
菜单->虚拟机->设置->勾选下图红色的两个
老师解释是:勾选后相当于虚拟机的网卡和物理机的网卡是两块网卡,但他们链接状态是一样的,也就是说物理机能ping的东西虚拟机也能ping。如果虚拟机想要和外面的机器ping通,那么虚拟机和物理机的IP地址必须是一个网段的(但IP不要一模一样?),测试时先ping物理机,再ping外面的IP(外面IP也要是同一个网段)