一、什么是socket编程:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket,编程传输层,socket本质是编程接口(API)
二、网络七层协议:物里层 数据链路层 网络层(IP) 传输层(TCP UDP) 会话层 表示层 应用层(HTTP协议)
三、套接字(协议,本地地址,本地端口):连接服务端和客户端,负责发送和接收数据
四、面向连接和无连接:建立连接后才能传输;不需要建立连接,只需要知道是谁就行
五、TCP三次握手:(三次是为了确认服务端收到)
1、 最开始都是closed状态,想要传输数据,服务端必须要变成监听状态(即listen状态)
2、 客户端发请求连接消息给服务端
3、 服务端给客户端发可以进行连接(确认)
4、 客户端向服务端发消息准备开始传输数据
CLOSED:起始状态,无任何连接。
LISTEN:服务端建立socket之后需要listen进入LISTEN(侦听)模式,侦听来自远方的TCP连接请求。
SYN_SENT:客户端建立socket之后需要connect服务器,向服务端发送SYN=j(随机数)申请连接,然后会进入SYN_SENT状态。
SYN_RCVD:服务端在** 侦听模式 **下收到SYN后会向客户端回应ACK=j+1,同时发送SYN=k,然后进入SYN_RCVD状态。
ESTABLISHED:客户端收到ACK后进行验证,同时回应服务端发来的SYN,返回ACK=k+1,然后进入ESTABLISHED状态。服务端收到最后一个ACK后验证,然后进入ESBABLESHED。表示双方的连接建立完成,可以进行数据传输。
六、TCP四次离手:ack=acknowledge,表示确认,关闭两次第一次是数据关闭,第二次是协议关闭
1、客户端给服务端发送消息FIN说数据传输完毕
2、服务端给客户端发送消息表示接收到客户端传输完信息的信息
3、服务端开始关闭,关闭完之后再给客户端发送消息告诉客户端已经关闭
4、客户端说我接收到你的关闭确认了
5、客户端状态变为time_wait后,会等待两倍包在网络上最大生存周期的时间(2*MSL时长),这时候只能等待服务器给返回数据,不能再使用端口发送消息
一般由客户端主动断开连接,服务端只做被动连接。但是如果有必要,服务端也可主动断开连接。
FIN_WAIT_1:在ESTABLISHED(连接)状态下,主动断开连接会向对端发送FIN,然后进入FIN_WAIT_1状态。
CLOSED_WAIT:被动断开连接的一端收到FIN之后,会回应ACK,然后进入CLOSED_WAIT状态,在CLOSED_WAIT状态下,连接只能发送数据不能接收数据。
FIN_WAIT_2:主动断开连接的一端收到FIN的ACK回应后会进入FIN_WAIT_2状态。此时无法再发送数据但是可以接受数据。
LAST_ACK:被动断开连接的一端在缓冲区数据发送完成后会发送FIN然后进入LAST_ACK状态。如果程序健壮性较差,在socket收到文件结束符之后没有关闭socket,此处不会发出FIN,导致连接停留在CLOSED_WAIT&FIN_WAIT_2状态。
TIME_WAIT:主动断开连接的一端在收到对端的FIN后回应ACK然后进入TIME_WAIT。此状态下连接已断开,但为了避免最后一个ACK在网络中迷路,而导致的状态紊乱,端口会被保留2*MSL的时长。
CLOSED:在TIME_WAIT状态停留时间达到2*MSL之后进入CLOSED状态,表示无任何连接。

客户端代码: import socket #链接服务端ip和端口 ip_port = ('127.0.0.1',9999) #生成一个句柄 sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #请求连接服务端 sk.connect(ip_port) #发送数据 sk.send(u'客户端发送'.encode("GBK")) #接受数据 server_reply = sk.recv(1024) #打印接受的数据 print server_reply.decode("utf-8") #关闭连接 sk.close() 服务端代码: import sys reload(sys) sys.setdefaultencoding("utf-8") import socket #开启ip和端口 ip_port = ('127.0.0.1',9999) #生成一个句柄 sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #默认sk = socket.socket(socket.AF_INF,socket.SOCK_STREAM) #绑定ip端口 sk.bind(ip_port) #最多连接数 sk.listen(5) print (u'进入监听状态...') #等待链接,阻塞,直到渠道链接 conn打开一个新的对象 专门给当前链接的客户端 addr是ip地址 conn,addr = sk.accept() #获取客户端请求数据 client_data = conn.recv(1024) #打印对方的数据 print (client_data) #向对方发送数据 conn.send('服务回复内容') #关闭链接 conn.close()