http://www.cnblogs.com/alex3714/articles/5830365.html
http://www.cnblogs.com/wupeiqi/articles/5040823.html
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)
socket和file的区别:
- file模块是针对某个指定文件进行【打开】【读写】【关闭】
- socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】
socket 服务端示例代码
import socket server = socket.socket() #获得socket实例 server.bind(("localhost",9998)) #绑定ip port server.listen() #开始监听 while True: #第一层loop print("等待客户端的连接...") conn,addr = server.accept() #接受并建立与客户端的连接,程序在此处开始阻塞,只到有客户端连接进来... print("新连接:",addr ) while True: #第二层loop data = conn.recv(1024) if not data: # 判断传来的是否是空数据。如果不判断,会造成服务端陷入死循环 print("客户端断开了...") break #这里断开就会再次回到第一次外层的loop print("收到消息:",data) conn.send(data.upper()) server.close()
粘包:
调用send时,数据并没有立刻发送给客户端,而是放到了socket的发送缓冲区,等缓冲区满了或数据等待超时(0.5秒),数据才会被真正发送到客户端。
这样把好几次小数据拼成大数据,再一次发送到客户端,可以提高IO利用率。但也产生了“粘包”问题,即,2次或多次数据粘在一起发送。
如何避免粘包:
1. time.sleep(0.5)
每次send结束后都主动形成数据等待超时,超时后为了清空缓冲区,会强制发送数据到客户端。不推荐
2. conn.recv(1024)
每次send结束后都接收服务端的回应。conn.recv()执行过程中,服务端状态变为阻塞,当收到客户端发送来的数据时,服务端为了清空当前缓冲区,会将上一次conn.send()的数据强制发到客户端