赞
踩
TCP/IP的应用层对应OSI的应用层、表示层和会话层: TCP/IP的传输层和网络互联层分别对应OSI参考模型的传输层和网络层; TCP/IP的主机到网络层对应OSI参考模型的数据链路层和物理层。
主机到网络层包含了数据链路层信息和物理层信息,这部分在PC上对应的是网络接口卡以及驱动;主机到网络层以上的三层协议都是Linux内核实现的。网络互联层也叫做路由层,负责数据包的路径管理,常见的网络设备路由器就工作在这一层;传输层负责控制数据包的传输管理,常见的协议有TCP 和UDP协议;应用层是用户最关心的,也是用户数据存放的地方,常见的有HTTP协议、FTP协议等。
IP协议主要用于实现寻址和分段,寻址是IP协议提供的最基本功能,IP协议根据数据包头中目的地址传送数据报文。在传送数据报文的过程中,IP协议可以根据目的地址选择报文在网络中的传输路径,这个过程称做路由。
ping地址时,会出现ttl值,当ttl为0时,将会丢弃数据包,常用的功能有源地址,目的地址等等
TCP(面向连接)双方必须连接成功才能发数据,类似打电话,主要用于对传输数据精确的情况,如传输指令。
UDP(面向报文)双方无须连接成功就能发数据,类似发短信,主要用于传输大数据量的情况,如视频
TCP与UDP对比
1、TCP面向连接(如打电话要先拨号建立连接) ;UDP是无连接的,即发送数据之前
不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,” 对多, 多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
目前常用的网络分析工具Ethereal。
字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。
大端:低地址存高字节,高地址存低字节,如:TCP/IP协议字节序
小端:低地址存低字节,高地址存高字节,如:X86系列CPU字节序
由于内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分。
TCP/IP协议规定,网络数据流应采用大端字节序,即低地址存高字节,高地址存低字节。
- #include <arpa/inet.h>
-
- uint32_t htonl(uint32_t hostlong);
- uint16_t htons(uint16_t hostshort);
- uint32_t ntohl(uint32_t netlong);
- uint16_t ntohs(uint16_t netshort);
- //h表示host,n表示network,l表示32位长整数,s表示16位短整数。
- //如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。
-
- 以上API可以做网络字节序和主机字节序的转换
- 创建socket对象
- int socket(int domain,int type,int protocol);
- domain用于指定使用的域,如tcp/ip协议的网络互联层协议。ipv4(AF_INET),ipv6(AF_INET6)
- type参数指定了数据传输的方式,SOCK_STREAM代表面向连接的数据流方式,SOCK_DGRAM代表无连接的数据报方式。另外socket提供了一种SOCK_RAW的模式。
- protocol指定协议类型,一般取0
经典的三次握手示意图。
服务端端工作流程:
1.socket函数建立socket
2.bind()函数创建的socket句柄绑定到指定tcp端口
3.listen()使socket处于监听状态,并且设置监听队列的大小
4.当客户端发送请求后,accept()函数接受客户端请求,与客户端建立连接
5.与客户端发送或者接收数据
6.通信完毕,调用close()函数关闭socket函数。
客户端工作流程如下:
1.使用socket函数创建socket
2.调用connect()函数向服务端socket发起连接
3.连接建立后,进行数据读写
4.数据传输完毕,使用close()函数关闭Socket
- int bind(int sockfd,struct sockadd *my_addr,socklen_t addrlen);
- fd是要绑定的socket句柄,由socket()函数创建
- 参数my_addr指向一个sockaddr结构,里面保存ip地址和端口号,
- 参数addrlen是sockaddr结构的大小,成功返回0失败返回-1
-
- int listen(int s,int backlog);
- s是要监听的socket句柄,backlog参数指定最多可以监听的连接数量为20个,如果函数调用成功则返回0,失败返回-1,并且设置全局变量为errno
-
- int accept(int s,struct sockaddr *addr,socklen_t *addrlen);
- 参数s是监听的套接字描述符;参数addr是指向sockaddr结构的指针; addrlen是结构的大小。如果调用成功,则accept()函数返回新创建的套接字句柄,失败返回-1,并且设置全局变量为errno。
- accept会创建新的套接字,socket床创建的套接字仍然处于监听连接状态。
-
- int connect (int sockfd, const struct sockaddr *serv_addr, socklen_taddrlen);
- connect()函数的作用是和服务器端建立连接。参数sockfd是套接字句柄;参数serv_addr指向sockaddr结构,指定了服务器IP地址和端口号;参数addrlen是serv_addr结构大小。
-
- ssize_t send (int s, const void *buf, size_t len, int flags);参数s是套接字句柄,buf是要发送的数据缓冲,len是数据缓冲长度,参数flags一般置0。如果发送数据成功,则返回发送数据的字节数,失败返回-1。
-
- ssize_t recv (int s, void *buf, size_t len, int flags);参数s指定要读取数据的套接字句柄, buf参数是存放数据的缓冲首地址, len参数指定接收缓冲大小,参数flags一般置0。当读取到数据时函数返回已读取数据的字节数,如果读取失败返回-1,另外,如果对方关闭了套接字, recv()函数会返回0。
面向连接的echo服务编程实例
利用本机Ip和8080端口,模拟客户端和服务端之间的通信。实现当收到客户端发送的字符串就在屏幕打印出来把字符串发送给客户端,如果客户端发送"quit",服务器端退出。
服务端相关代码如下
客户端相关代码如下
总结网络通信的四种形式:
udp客户端
udp服务端
tcp客户端
tcp服务端
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。