前言
今天学习了一些Python Socket的知识,现在把它记录下来.
1.socket简介
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。
注:这些概念我也不是很理解.我对socket的理解是:socket可以实现服务端与客户端之间的通信.
2.python实现一个简单的socket网络通信
服务端 socket_server.py
import socket
server = socket.socket() # 声明socket类型,同时生成socket链接对象
server.bind(('localhost',6968)) # 绑定要监听的端口
server.listen(5) # 开始监听端口
print('开始监听:')
conn,addr = server.accept() # 等待客户端发送消息
print(conn)
print(addr)
print('监听到消息')
data = conn.recv(1024) # 接收客户端发来的消息
print('server recv:',data)
conn.send(data.upper()) # 将客户端发来的消息进行大写并返回给客户
server.close() # 关闭
客户端 socket_client.py
import socket
client = socket.socket() # 声明socket类型,同时生成socket链接对象
client.connect(('localhost',6968)) # 连接本地的6969端口
client.send(b"hello world!") # 向服务端发送消息
data = client.recv(1024) # 接收服务端发回来的消息
print('client recv:',data)
client.close() # 关闭客户端
注:这里只是实现了一个最简单的服务端与客户端的通信,只能完成"一来一回".
代码解释:
(1) 服务端:
服务端要做的事情就是监听客户端的访问端口,然后接收客户端的访问信息,并将相关信息返回给客户端.
第一步,创建socket对象,声明socket类型
import socket
server = socket.socket() # 声明socket类型,同时生成socket链接对象
第二步,将socket绑定到指定地址.socket.bind()方法是绑定端口,这里只接收一个参数,所以要传入一个元组.
server.bind(('localhost',6968)) # 绑定要监听的端口
第三步,开始监听端口.注:server.listen()方法会接收一个参数,意思是最大监听数.
server.listen(5) # 开始监听端口
第四步,等待客户端发送消息.运行accept()方法后,socket进入等待状态,等待客户请求连接.当用户请求连接时,accept()建立连接,返回两个值conn和addr.其中conn是新的socket对象,服务器要通过这个新的socket对象与客户端进行通信,addr是客户端的internet地址.
conn,addr = server.accept() # 等待客户端发送消息
第五步,接收客户端发来的消息,这里要使用新的socket对象conn来与客户进行交流.
data = conn.recv(1024) # 接收客户端发来的消息
第六步,向客户端发送消息.这里只是将客户端发来的消息变成大写返回给客户端.
conn.send(data.upper()) # 将客户端发来的消息进行大写并返回给客户
第七步,关闭服务端.
server.close() # 关闭服务端
(2)客户端
客户端做的事情就是访问服务端,并向服务端出入数据,同时接收服务端返回的数据.
第一步,创建socket对象.声明socket类型
import socket
client = socket.socket() # 声明socket类型,同时生成socket链接对象
第二步,连接服务端
client.connect(('localhost',6968)) # 连接本地的6969端口
第三步,向服务端发送消息
client.send(b"hello world!") # 向服务端发送消息
第四步,接收服务端发送来的消息
data = client.recv(1024) # 接收服务端发回来的消息
第五步,关闭客户端
client.close() # 关闭客户端
运行结果:
打开两个终端,一个运行服务端,一个运行客户端,一个运行服务端.
注:我的运行环境为ubuntu16.04,python3.5.2
服务端展示–python socket_server.py
客户端展示–python socket_client.py
注:这里只是实现了一个非常简单的类似于"一问一答"形式的socket通信,显然这不符合我们的习惯,接下来就实现一个服务端可以一直监听客户端访问,并且客户端也可以一直和服务端进行通信.
3.python socket通信改进
服务端 socket_server_2.py
'''
服务端
'''
import socket
server = socket.socket() # 创建socket对象,声明socket类型
print('server = ',server)
server.bind(('localhost',6600)) # 绑定要监听的地址和端口
print('开始监听端口:')
server.listen(5) # 最多允许挂起5个链接
'''
内层循环的作用:与一个客户进行交流,当这个客户断开时,就回到外循环
外循环的作用:外循环一直在监听客户端的访问,当一个客户端断开后,就监听新的客户端的访问
这样就可以实现当一个客户端关闭时,另一个客户端就可以进行访问
但是还不能实现多个客户端同时访问
'''
while True:
conn, addr = server.accept()
print('客户端连接成功')
print('conn = {},addr = {}'.format(conn,addr))
while True:
data = conn.recv(1024)
print('服务端接收的数据为: ',data.decode())
if not data:
print('客户端已关闭')
break # 注:这个break只是跳出了内层循环
conn.send(data.upper())
server.close()
客户端 socket_client_2.py
'''
客户端
'''
import socket
client = socket.socket() # 创建Socket对象,声明socket类型
client.connect(('localhost',6600))
while True:
msg = input("请输入: ")
if len(msg) == 0:
continue
client.send(msg.encode('utf-8'))
data = client.recv(1024)
print('客户端接收的数据为: ',data.decode())
client.close()
代码解释:
(1) 服务端:
服务端采用两个while循环,内层循环的作用是与一个客户进行交流,当这个客户断开时,就回到外循环,继续监听其他客户端的访问,外层循环的作用是一直监听客户端的访问,当一个客户端断开时,就监听其他的客户端的访问.
(2) 客户端:
客户端就是采用了一个while循环来实现.
运行结果:
服务端–python socket_server_2.py
服务端–python socket_client_2.py
写在最后:
这些内容只是我自己的见解,不到之处请多多批评指正.内容如有侵权,请及时联系我,感谢大家!