前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python3--socket编程(tcp协议)

python3--socket编程(tcp协议)

作者头像
py3study
发布2018-08-02 17:11:43
1.7K1
发布2018-08-02 17:11:43
举报
文章被收录于专栏:python3

socket概念

socket层

blob.png
blob.png

理解socket

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议

简单来说

代码语言:javascript
复制
其实站在你的角度上看,socket就是一个模块。我们通过调用模块中已经实现的方法建立两个进程之间的连接和通信。
也有人将socket说成ip+port,因为ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序。
所以我们只要确立了ip和port就能找到一个应用程序,并且使用socket模块来与之通信。

套接字(socket)的发展史

套接字起源于 20 世纪 70 年代加利福尼亚大学伯克利分校版本的 Unix,即人们所说的 BSD Unix。 因此,有时人们也把套接字称为“伯克利套接字”或“BSD 套接字”。一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的

基于文件类型的套接字家族

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

基于网络类型的套接字家族

套接字家族的名字:AF_INET

(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET)

tcp协议和udp协议

.TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;电子邮件、文件传输程序。

UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)

blob.png
blob.png

套接字(socket)初使用

基于TCP协议的socket

tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端

windows如果不通,注意关闭防火墙

server端

代码语言:javascript
复制
import socket

sk = socket.socket()  # 实例化一个对象sk
sk.bind(('192.168.11.224', 8989))  # 把地址绑定到套接字
sk.listen()  # 监听链接

conn, addr = sk.accept()  # 接收客户端链接
print(addr)  # 打印出客户端的地址+端口
conn.send('hello'.encode('utf-8'))  # 向客户端发送信息
ret = conn.recv(1024)  # 接收客户端信息(1024字节)
print(ret.decode('utf-8'))  # 打印客户端信息(bytes类型需要decode)
conn.close()  # 关闭客户端套接字
sk.close()  # 关闭服务器套接字

client端

代码语言:javascript
复制
import socket

sk = socket.socket()  # 创建客户端套接字
sk.connect(('192.168.11.224', 8989))  # 连接服务器(ip地址+端口)

ret = sk.recv(1024)  # 接收消息
print(ret.decode('utf-8'))  # 打印接收的消息
sk.send('SB!'.encode('utf-8'))  # 向服务器发送消息(bytes)
sk.close()  # 关闭客户端套接字

选运行server端,在运行client端(顺序不能搞反了!)

server端执行结果如下

('192.168.11.224', 58040)

SB!

client端执行结果如下

hello

上面例子,只是互相发送了一次消息,就关闭了,如何互相一直发送消息?

server代码:

代码语言:javascript
复制
import socket

while True:
    sk = socket.socket()  # 实例化一个对象sk
    sk.bind(('192.168.11.224', 8989))  # 把地址绑定到套接字
    sk.listen(10)  # 监听链接
    conn, addr = sk.accept()  # 接收客户端连接信息
    print(addr)  # 打印出客户端的地址
    ret = conn.recv(1024)  # 接收客户端信息(1024字节)
    if ret.decode('utf-8').lower() == 'q':  # (一定要是client先退出,读取内容为q,则退出)
        conn.close()  # 关闭客户端套接字
        sk.close()  # 关闭服务器套接字
        break
    print(ret.decode('utf-8'))  # 打印客户端发送信息
    content = input('input>>>').strip().encode('utf-8')  # 输入需要发送的内容
    conn.send(content)  # 向客户端发送信息

client代码:

代码语言:javascript
复制
import socket

while True:
    sk = socket.socket()  # 创建客户端套接字
    sk.connect(('192.168.11.224', 8989))  # 连接服务器(ip地址+端口)

    content = input('input>>>').strip().encode('utf-8')  # 输入内容,需要encode为bytes类型
    if content.decode('utf-8').lower() == 'q':  # 当输入q的时候,退出聊天
        sk.send(content)  # 关闭前发送退出信息给server端
        sk.close()  # 关闭客户端套接字
        break
    sk.send(content)  # 向服务器发送消息(bytes)

    ret = sk.recv(1024)  # 接收消息
    print(ret.decode('utf-8'))  # 打印接收的消息

运行效果--(先执行server,在执行client)

download.gif
download.gif

socket(tcp协议)编程,多人聊天

对于一个tcp连接,客户端和server对话没有结束,那么其它客户端全部都不能与服务器发消息对话

示例

server端代码

代码语言:javascript
复制
import socket

sk = socket.socket()  # 实例化一个对象sk
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # 重用ip和端口
sk.bind(('127.0.0.1', 9595))  # 把地址,端口绑定到套接字(socket)
sk.listen()  # 监听连接

# 网络传输只能是二进制(bytes)类型的数据
while True:
    conn, addr = sk.accept()  # 接收客户端连接(conn为内容,addr为ip地址和端口)
    while True:
        ret = conn.recv(1024).decode('utf-8')  # 接收内容1024个字节并解码为utf-8
        if ret == 'q':
            break
        print(ret)
        inp = input('>>>').strip()
        conn.send(inp.encode('utf-8'))  # conn.send发送信息(并编码成utf-8)
        if inp == 'q':
            break
    conn.close()  # 关闭客户端连接

sk.close()  # 关闭socket连接

client端代码

代码语言:javascript
复制
import socket

sk = socket.socket()  # 实例化一个对象sk
sk.connect(('127.0.0.1', 9595))  #连接服务器(ip地址+端口)
while True:
    inp = input('>>>').strip()
    sk.send(inp.encode('utf-8'))  # 向服务器发送消息(编程成utf-8)
    if inp == 'q':
        break
    ret = sk.recv(1024).decode('utf-8')  # 接收消息(1024字节,解码成utf-8)
    if ret == 'q':
        break
    print(ret)
sk.close()  # 关闭socket连接

运行结果

download.gif
download.gif

可以很明显的看到,如果第一个连接不退出的话,那么第二个连接就不能与服务器对话

总结:

tcp协议适用于 文件的上传和下载 发送邮件 发送重要文件

每和一个客户端建立连接,都会在自己的操作系统上占用一个资源

同一时间,只能和一个客户端通信

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/05/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档