python网络编程,socket编程

本文介绍了Python中的套接字编程,包括创建套接字、服务器端与客户端编程、并发编程和非阻塞编程等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文简要介绍对套接字的网络编程。套接字是结算及网络数据结构,体现的是“通信端点”的概念。网络应用程序在进行任何通信之前,必须先创建套接字。

一、主要函数介绍:

Python中的网络编程,主要使用socket模块的函数。

socket =》创建套接字对象,socket(s ocket_family ,  socket_type ,  protocol =0)

服务器端的方法:

bind =》绑定地址到套接字

listen =》启动TCP监听

accept =》 接受客户端连接

客户端的方法:

connect =》初始化一个TCP服务连接

数据发送和接收:

recv =》接收数据

send =》发送数据


二、服务器端简单的socket编程

1、创建socket:

import socket
from time import ctime

HOST = ''
PORT = 21567
BUFSIZE = 100 #一般取1024,可以自己根据需要调整。
ADDR = (HOST, PORT)

# 创建socket并监听本地端口.
tcpServerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpServerSock.bind(ADDR)
tcpServerSock.listen(5)
2、接受客户端连接,接收并发送数据

print("等待连接......")
tcpClientSock, addr = tcpServerSock.accept()
print("... 客户端的地址为:", addr)
while True:
#内循环,处理客户端数据的发送和接收。
data = tcpClientSock.recv(BUFSIZE)
if not data:
break
recData = data.decode() #二进制数据转换为字符串。默认utf-8
print("从客户端收到的数据:", recData)
sendData = "[%s] %s"%(ctime(), recData)
tcpClientSock.send(sendData.encode())
tcpClientSock.close()

tcpServerSock.close()

三、客户端socket编程

1、建立TCP连接

import socket

HOST = 'LOCALHOST'
PORT = 21567
BUFSIZE = 100
ADDR = (HOST, PORT)

tcpClientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpClientSock.connect(ADDR)
2、定义发送函数

def send01(sock, msg):
# 在网络不忙的时候,send函数每一次都会将全部的数据发送出去,一帮情况下会工作的很好。
sock.send(msg.encode())
3、发送数据到服务器并接收服务器的数据

data = input('> ')
if not data:
break
sendtotal(tcpClientSock, data)
data = tcpClientSock.recv(BUFSIZE)
if not data:
break
recData = data.decode() #将二进制数据转换为字符串数据。
print("从服务器上收到的数据:%s"%(recData))

4、网络繁忙时发送数据的方法

def sendtotal(sock, msg):
#判断send发送的字节数, 直到全部发送完。
totalsent = 0
data = msg.encode()
datalen = len(data)
while totalsent < datalen:
sent = sock.send(data[totalsent:])
if sent == 0:
raise RuntimeError("socket连接中断")
totalsent = totalsent + sent

四、并发socket编程

上述简单的socket编程方法,最多只能处理一个客户端的连接。python具有强大的线程处理能力,我们可以将线程与socket编程混合到一起,就可以同时处理多个客户端的连接。

1、自定义socket线程类:

class SocketThread(threading.Thread):
"""自定义socket线程类"""
def __init__(self, sock):
threading.Thread.__init__(self)
self.sock = sock

def run(self):
while True:
# 内循环,处理客户端数据的发送和接收。
data = self.sock.recv(BUFSIZE)
if not data:
break
recData = data.decode() # 二进制数据转换为字符串。默认utf-8
print("从客户端收到的数据:", recData)
sendData = "[%s] %s" % (ctime(), recData)
self.sock.send(sendData.encode())
self.sock.close()
2、SocketThread的使用

def client_thread(sock):
"""创建socket线程"""
t = SocketThread(sock)
return t
pass

#外循环,等待客户端连接
while True:
print("等待连接......")
tcpClientSock, addr = tcpServerSock.accept()
print("... 客户端的地址为:", addr)
ct = client_thread(tcpClientSock)
ct.start() #启动线程

5、非阻塞socket编程

在使用线程来处理多个socket连接的问题时,受限于机器资源,线程是昂贵且有限的资源,同时处理的socket连接数毕竟有限。

下面就介绍一下python中非阻塞socket是如何处理的。

1、简介:

非阻塞socket编程主要依赖于select模块,该模块提供了特定平台的I/O监视函数。最轻便的方法就是POSIX功能的select()函数,在unix和windows平台上都可用。

readable, writable, exceptional = select.select(inputs, outputs, inputs)

select方法会返回三个socket列表,分别为读列表,写列表,异常列表,然后分别对这三个列表的socket进行处理。

2、select方法的使用:

import socket
import select
import queue
from time import ctime

HOST = ''
PORT = 21567
BUFSIZE = 1024 #一般取1024,可以自己根据需要调整。
ADDR = (HOST, PORT)

# 创建socket并监听本地端口.
tcpServerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpServerSock.setblocking(0)
tcpServerSock.bind(ADDR)
tcpServerSock.listen(5)

# 准备读数据的socket列表。
inputSockets = [tcpServerSock]
#准备发送数据的socket列表。
outputSockets = []
#输出的消息队列。
message_queues = {}
print("等待连接......")
readable, writable, exceptional = select.select(inputSockets, outputSockets, inputSockets)
3、对读socket列表的处理:

for s in readable:
#处理读的socket
if s is tcpServerSock:
clientConnection, addr = tcpServerSock.accept()
print("... 客户端的地址为:", addr)
clientConnection.setblocking(0)
inputSockets.append(clientConnection) #放到读取数据列表中。
#每一个connection一个发送数据的队列。
message_queues[clientConnection] = queue.Queue()
else:
data = s.recv(BUFSIZE)
if data:
print("从%s接收到数据%s" % (s.getpeername(), data.decode()))
message_queues[s].put(data)
if s not in outputSockets:
outputSockets.append(s)
else:
print("关闭客户端%s,没有读取到数据." % (addr))
if s in outputSockets:
outputSockets.remove(s)
inputSockets.remove(s)
s.close()
#删除当前socket对应的消息队列。
del message_queues[s]
4、对写socket列表的处理:

#处理数据发送队列。
for s in writable:
try:
next_msg = message_queues[s].get_nowait()
except queue.Empty:
print("%s的输出队列为空" % ("ddddd"))
outputSockets.remove(s)
else:
print("发送数据 %s 到 %s" % (next_msg, s.getpeername()))
s.send(next_msg)
5、对异常socket列表的处理:

for s in exceptional:
print("与%s的通信产生异常,连接将被断开"%(s.getpeername()))
inputSockets.remove(s)
if s in outputSockets:
outputSockets.remove(s)
s.close()
del message_queues[s]

备注:

完整源代码可以搜索:python网络编程




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值