写代码的运维妞

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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()的数据强制发到客户端 

posted on 2017-03-15 15:45  kayegao  阅读(212)  评论(0编辑  收藏  举报