模块socket使用
Posted zhuchunyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模块socket使用相关的知识,希望对你有一定的参考价值。
什么是socket:socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。我们无需再去深入理解tcp/udp协议,按照socket的规定去使用就行了。
首先一个c/s架构:分为两部分,服务端,客户端 (讲解基于tcp协议,传输数据)
服务端是怎么设置的呢
import socket #首先导入socket模块
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #这是获取tcp套接字(流式协议)
# server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #这是获取udp套接字
server.bind((‘127.0.0.1‘,8080)) #然后就是绑定服务器的ip和端口,记住bind()括号里加(ip,端口) 是一个元组形式的
server.listen(5) #括号是监听数,比如我们设置为5,当服务端正在跟五个客户端通信时,再来一个客户端,那个客户 端就会连接不进去。
# a = server.accept() #这里就是等待着客户端连接,当有客户端连接时 a = (一个具有客户端到服务端和一个服务端到客户端的套接字,客户端的ip和端口) a 是一个元组类型的数据,我们可以通过解压的方式,分别讲他们赋值给conn和client_addr 也就是以下的代码
conn,client_addr = server.accept() # 我们可以通过这个coon 跟客户端收发信息,这是
data = conn.recv(1024) #这是收取客户端的信息,1024代表一次性接收最大是1024字节的数据。将接收的信息赋值给data 记住data 现在是二进制类型数据
conn.send(data.upper()) #这里我们将接收的数据大写形式发送过去。 你也可以发送其他数据过,这只是一种例子而已。发过去的数据没有大小的限制。但是注意接收一次性最多接收1024大小的字节。
conn.close() #通信结束了的话,记得关闭conn这个套接字。这个f.open() 记得f.close()是差不多的
server.close() #关闭服务端。严格来说服务端的作用就是一直对外开放服务的,一般来说不用关闭。
下面是客户端的搭建,其方法和服务端一样的
import socket
client = socket.socket() #这里括号里不填的话,就是默认tcp协议(流式协议),前面服务端也是一样。
client.connect((‘127.0.0.1‘,8080)) #这里就是直接去连接服务端。记住ip和端口是元组形式。
client.send(‘你好呀,我是客户端‘.encode(‘utf-8‘)) #记住你发过的数据必须是二进制。可以通过encode(‘utf-8‘)转换
data = client.recv(1024) #收到服务端的信息
print(data.deconde(‘utf-8‘)) 打印信息
client.close() 关闭客户端
以上就是通过socket模块搭建的c/s架构(基于tcp协议)
udp协议理论方法是一样的。我就不一一介绍了。
上面就是一个最基本的c/s架构。但是健壮性可能不太行。我们可以通过在上面模板在上面增加代码。
隐藏错误1:客户端和服务端两者都建立的连接,如果客户端这边出于某种不正常断开的话,那么服务端的就是崩掉。
解决方法一:就是通过捕捉异常的方式。
try:
data = conn.recv(1024)
conn.send(data.upper())
except ConnectionResetError:
break
解决方式二:其实在windows系统下,解决方式一就够了,但是我们以后还会在linux在运行,所以说呢,在解决方式二就使用于linux系统,我们写这个windows的时候也没有影响,防止以后再linux下出错了。
基于上面的改进,以后就写这种
try:
data = conn.recv(1024) #正常情况(客户端没有意外断开,能正常和服务端通信),data 永远不会接收到空值,他只会接收有大小的数据。 注意!!!
if not data : break #只有在客户端意外断开后,在linux系统下才会运行这段代码,正常情况是不会运行的。
conn.send(data.upper())
except ConnectionResetError:
break
基于解决方法二,我有一点强调的写在上面。
隐藏错误2 :客户端不能输入空,这样会导致服务端接收不到数据,在那里一直等着,客户端虽然发出了数据,但接收数据状态永远接收不到值。会一直在那里等待服务端的发过来的数据。你可以基于上面的模板去试试。
解决方式很简单,就是不让客户端发送空值就行了,就是多加了一条判断语句。
msg = input(‘客户端要发送到内容‘).strip()
if not msg : continue #基于可循环通信,也就是客户端收发信息在一个while循环里。前面服务端可以这样
这就是几个会出现的小错误和解决的方案。
以上是关于模块socket使用的主要内容,如果未能解决你的问题,请参考以下文章