目录
1. 网络通信三要素:
- A:IP地址:
(1)用来标识网络上的一台独立主机
(2)IP地址 = 网络地址 + 主机地址
(3)特殊地址:127.0.0.1 代表本机地址(一般用于测试) - B:端口号:
(1)用来标识进程的逻辑地址
(2)不同进程有不同的逻辑地址 - C:传输协议:
(1)通讯的规则:TCP、UDP
(2)TCP协议经过三次握手,传输可靠,但效率低,速度慢
(3)UDP直接扔过去,不管是否对方有相应,传输速度高,可靠性低,一般用于视频、语音通话
2. 利用sock模块进行通信流程
服务端:my_server.py
# Author:AD
# Date:2020/3/8
import socket
# 1.建立socket对象
sk = socket.socket()
# 2.绑定服务器地址,端口号设置1000以后即可
addr = ('127.0.0.1', 8000)
sk.bind(addr)
# 3.设置等待数目(客户端有可能有很多,此方法设置最多等待)
sk.listen(3)
# 4.等待客户端连接, 此时无客户端连接会产生阻塞(返回可客户端socket对象和地址)
conn, conn_adrr = sk.accept()
print(conn, conn_adrr)
# 5.【接收、发送消息】需要保持一收一发一致,客户端可服务端需要配合使用
# 【接收】参数为bytes数目,必须有
data = conn.recv(1024)
# 【发送】send 方法和sendall方法都可,不过send有可能发不完,一般用sendall
conn.sendall(data)
# 6. 服务结束,关闭客户端
conn.close()
客户端:my_client.py
# Author:AD
# Date:2020/3/8
import socket
# 1. 建立socket对象
sk = socket.socket()
# 2. 建立链接地址,当服务器开启才能成功链接,否则报错
addr = ('127.0.0.1', 8000)
sk.connect(addr)
# 3.【收、发逻辑】需要和server端同步编程,并且必须是bytes型
s = bytes('test', 'utf8')
sk.sendall(s)
date = sk.recv(1024)
print(str(date, 'utf8'))
以上代码成功进行链接并进行test传输
3. socket下的方法简介
服务端(server)
.bind(address) 服务器绑定地址,地址为IP和Port组成的元组
.listen(n) 服务器设置最大等待的client的数目
.accept() 服务器等待链接的的关键方法,返回client对象和地址
客户端(client)
.connet(address) 客户端链接服务端方法,地址为元组
两个都有
.send(data) 发送内容为字节型,只发送一部分
.sendall(data) 全发送
.recv(1024) 接收,必须设置参数,一般是1024字节一波
conn.recv(1024)
该方法如果没有读到数,则会产生阻塞,在该句下面等待内容。
如果此时,conn自己close或者被服务器close了,该方法返回b’’,并继续朝下走。
而如果强制关闭客户端了,将会报错(linux下不会),因此在服务器端最好用异常进行判断。
.settimeout(time):设置超时时间,还没用过
4. 循环聊天机制实现
server端:
# Author:AD
# Date:2020/3/8
import socket
# 基本操作
sk = socket.socket()
addr = ('127.0.0.1', 8000)
sk.bind(addr)
sk.listen(3)
# 实现循环聊天,q 退出,server不进行输入,简单些
while True:
# 以下模块实现循环链接,但是如果强制关闭client会报错
conn, conn_adrr = sk.accept()
print(conn_adrr)
# 实现链接内循环收发
while True:
data = conn.recv(1024)
s_recv = str(data, 'utf8')
print(s_recv)
#退出逻辑
if s_recv == 'q':
break
conn.sendall(data)
# 关闭当前client
conn.close()
client端:
# Author:AD
# Date:2020/3/8
import socket
sk = socket.socket()
addr = ('127.0.0.1', 8000)
sk.connect(addr)
while True:
# 发送逻辑
s = input('>>>')
data = bytes(s, 'utf8')
sk.sendall(data)
# 退出逻辑
if s == 'q':
break
# 接收逻辑
s_recv = sk.recv(1024)
print(str(s_recv, 'utf8'))
sk.close()
运行结果:可以同时开四个,另外三个输入:你好2、你好3、你好4,并回车进行等待,然后第一个输入:你好1。
之后从第一个开始依次输入 q,得到server端的运行结果:
但是如果进行强制关闭客户端,服务端并不会直接越过.recv()语句,而是报错:
5. 实现强制关闭客户端不报错功能
只改变server端,加入报错逻辑
# Author:AD
# Date:2020/3/8
import socket
# 基本操作
sk = socket.socket()
addr = ('127.0.0.1', 8000)
sk.bind(addr)
sk.listen(3)
# 实现循环聊天,q 退出,server不进行输入,简单些
while True:
# 以下模块实现循环链接,但是如果强制关闭client会报错
conn, conn_adrr = sk.accept()