只要在一个电脑中的两个进程之间可以通过网络进行通信那么拥有公网ip的两个计算机的通信是一样的。但是一个局域网中的两台电脑上的虚拟机是不能进行通信的,因为这两个虚拟机在电脑中又有各自的局域网所以通信很难实现。
socket套接字是一种用于网络间进行通信的方式,通过tcp与udp以及ip的方式与另外一个主机进行通信,为什么从传输层往下进行计算,因为应用层的方式协议非常的灵活,只要是有一个头和内容即可。
Linux在主机端都是小端存储的,在网络端是大端进行存储的,记忆方式就是那个图这个是大端存储的方式。
所以说将在主机端的信息发布到网络上的时候需要先将信息将小端的方式转化为大端的方式。
【注意】区分大小端的时候是按字节进行划分的,字节内的数据是有序的。分为高字节和低字节,所以可以通过将数据打印为char类型数据判断(ASCII)
【注意】转换端口或者是ip进行大小端的转化需要使用不同的函数因为两者的长度不同。
htonl32位的(host与net)【转化ip】将ip主机字节序转化为网络字节序。
htons16位的【转化端口】将端口的主机字节序转化为网络字节序。
当然可以转过去也可以转回来,ntohl和ntohs函数
大小端的转换并不常用,因为我们常常使用char *字符串类型,所以使用下面的函数
一般在写的时候都是char *ip字符串类型,在进行传输的不便于使用192.如果是字符串类型仅这一小部分这个就是三个字节,所以将这个点分十进制转化为32位01数转化为int类型数字
int inet_aton(char *ip, struct in_addr*inp)将char*类型转化为大端方式转化为struct in_addr,与下面的函数有区别
in_addr_t inet_addr(char *ip)将char*转化为in_addr_t类型(小端的方式)
char* inet_ntoa()将大端转化为char*
存储IP和端口定义的结构体struct sockaddr_in存储ipv4类型数据
【注意】但是一套接口接口可以适用于ipv4和ipv6的通信,所以bind等函数中使用这样一种struct sockaddr通用的一个类似的说明符实际上却没有这样的一个结构体定义,所以在实际应用的时候将sockaddr_in或者sockaddr_in6强转为sockaddr类型
【注意】sockaddr_in 是一个socket类,型的结构体存储ipv4 or 6,存储ip只是这个ipstruct in_addr类型存储用和端口号。struct in_addr 与 in_addr_t类型是一 一对应的,就是说在结构体中实际上存储的就是in_addr_t,所以说在使用的时候注意区分两者。
DNS dns将域名转化为ip
可以多个域名映射同一个ip,可以多个ip映射同一个域名(例如百度)。
gethostbyname给域名变ip,得到更多细节的函数是getaddrinfo函数可以通过一个域名得到所有的ip地址。
socket基于TCP进行通信的方式
socket设置一个socket节点(理解为开辟一片区域,分配一个名字)
bind就是设置服务器监听的端口,还有ip???????????
listen?????????????
【注意】在服务器端是自己设置一个端口,在客户端进行随机分配端口,因为客户端如果也是固定端口,这样的话不同的服务程序可能产生冲突,所以采用固定端口的方式。
connect进行三次握手
accept在accept的时候是将原来的socket端点进行复制一个socket节点进行通信。
然后就是借助send和recv进行通信。
最后通过close进行四次挥手。
框架:
通过网络通信(考虑传输层和网络层socket定义)(应用层的传输规定相当的灵活不需要)--------》将主机上的数据传递到网络上去(注意数据存储的大小端的问题)--------》
注意一些问题:
1. 在主机和网络上进行传输时注意大小端问题
2. 注意区分struct in_addr 与 in_addr_t其实一回事,struct中有in_addr_t