由于作者我遇到了一些疑难问题,原本上周应该到来的更新,被我拖稿了。。。
接下来进入我们今天的主题,Linux的网络编程。其实我只是根据socket编程通过简 单一个TCP 和HTTP程序来帮助大家了解一下Linux的网络编程,真正的网络编程还 需要诸位自行挖掘,在真谛中体会强大。
所谓的TCP是一种传输协议,TCP/IP则是数据传输的协议簇,TCP是一种面向连接 的、可靠的、基于字节流的通信协议,TCP工作在传输层,UDP也是传输层协议,但 比较TCP相对简单,这里就不做具体介绍。
TCP的连接有三次握手,断开连接有四次握手
客户端发送SYN报文给服务器端
服务器端收到SYN报文,回应一个SYN和ACK报文
客户端收到服务器端的SYN报文,回应一个ACK报文
三次握手完成,TCP客户端和服务器端成功地建立连接,可以开始传输数据了。
由于TCP的半关闭机制导致断开连接需要四次握手
某一断使用close,并且发送FIN信号,表示数据发送完毕
接受FIN的对方,发送确认
过一段响应时间,接受FIN一方未收到对方数据传输,调用close,发送FIN断开连接
经过四次握手双方都断开了连接
Linux下的SOCKET编程比较Windows有许多方便之处,尤其是SOCK_RAW
下面来介绍程序的流程和实现方式,我尽可能不用实现代码,使用伪代码更好的帮助 大家理解
客户端:
首先是封装struct sockaddr_in 用于存储服务端和本端的ip、端口等信息结构体
填充sockaddr_in定义的一个结构体,注意字节顺序的转换
客户端使用connect对服务器端进行连接,之后使用内核函数read来接收数据即可
如果使用多线程编程,数据传输更加有调理,也不会出现死锁的状况。
将接收函数或者发送函数放到一个新开的线程中即可,无需两者都放入线程中
在接收函数中注意清空缓冲区,不然会出现字符串乱码。
服务器端:
相对于客户端,服务器端就比较麻烦,需要绑定端口和IP信息,需要循环接收客户端 连接请求,同时还要发送和接收数据。
首先封装
struct sockaddr_in
,这里要使用两个,一个用于存储服务器本身,一个存 储客户端,一个存储客户端。
bind绑定本地信息,listen监听访问本地端口的客户端,accept接收访问服务器的用 户信息。
Linux下不需要输出话WSA(Windows Sockets Asynchronous的简称)。可以直接 使用相关处理函数。
接下来,介绍HTTP的GET方法实现
HTTP是应用层协议,其访问方式和SOCKET编程中一样,对IP:端口进行访问。
只是建立连接之后,发送的数据有所区别,这个就需要对HTTP响应头、请求头进 行分析。
通过抓包可以看出请求头、响应头。
Telnet www.baidu.com 80
HEAD /index.html HTTP/1.1
(空两行)
可以使用telnet对报文进行查看
编写发送的数据包以上述格式封装。
获得的响应包数据是对应网站的HTML布局文件。