当前位置:首页>python>Python-Socket模块

Python-Socket模块

  • 2026-08-27 22:07:38
Python-Socket模块

介绍

Python中的socket模块提供了底层的网络接口,使用Python的socket模块可以实现网络上不同计算机之间的socket通信。Python中的socket实现了BSD(Berkeley Software Distribution)套接字标准。

使用socket模块建立网络通信

创建对象

创建一个socket对象,然后即可使用socket对象的方法创建连接。socket()函数的原型如下。

socket( family, type, proto) 

其参数含义如下。

  • family 地址系列,可选参数。默认为AF_INET,也可以是AF_INET6或AF_UNIX。
  • type socket类型,可选参数。默认为SOCK_STREAM。
  • proto 协议类型,可选参数。

绑定对象

可以使用socket对象的bind方法绑定IP地址和端口。bind方法的原型如下。

bind(address) 

其参数含义如下。

  • address 由IP地址和端口组成的元组,如“(‘127.0.0.1’,1051)”。如果IP地址为空,则表示本机。

监听连接

使用socket对象的listen方法可以监听由socket对象创建的连接。其函数原型如下。

listen(backlog) 
  • 其参数含义如下。 backlog 指定连接队列数,最小值为1,最大值由所使用的操作系统决定,一般情况下为5。

连接到服务端

使用socket对象的connect和connect_ex都可以连接到服务端,不同的是,当连接不成功时,connect将返回一个错误,而connect_ex则引发一个异常。其函数原型如下。

connect(address) 
connect_ex(address) 

其参数含义相同,如下所示。

  • address 由IP地址和端口组成的元组。

接受来自客户端的连接

使用socket对象的accept方法可以接受来自客户端的连接,accept方法将返回一个新的socket对象和客户端的地址。使用socket对象的recv和recvfrom方法都可以从socket对象获取数据,不同的是,recvfrom方法返回所接受的字符串和地址,而recv方法仅返回字符串,其原型如下。

recv(bufsize, flags) 
recvfrom(bufsize, flags) 

其参数含义相同,如下所示。

  • bufsize 指定接受缓冲区大小。
  • flags 接受标志,可选参数。

发送数据

使用socket对象的send和sendall方法都可以向已经连接的socket发送数据,不同的是,sendall将一次发送完全部数据。其原型如下。

send(string, flags) 
sendall(string, flags) 

其参数含义相同,如下所示。

  • string 所发送的数据。
  • flags 发送标志,可选参数。

一个未连接的socket发送数据

使用socket对象的sendto方法可以向一个未连接的socket发送数据,其参数原型如下。

sendto(string, flags, address) 

其参数含义如下。

  • string 所发送的数据。
  • flags 发送标志,可选参数。
  • address 由IP地址和端口组成的元组。

关联到文件对象上

使用socket对象的makefile方法可以将socket关联到文件对象上,其原型如下。

makefile(mode, bufsize) 

其参数含义如下。

  • mode 文件模式,可选参数。
  • bufsize 缓冲区大小,可选参数。

关闭连接

当完成通信后,应使用socket对象的close方法关闭网络连接。

示例

发送数据

服务端程序

#-*- coding:utf-8 -*- 
#file: server.py 
#
import tkinter 
import threading 
import socket 

classListenThread(threading.Thread):# 监听线程 
def__init__(self,edit,server):
        threading.Thread.__init__(self) 
        self.edit = edit                                # 保存窗口中的多行文本框 
        self.server = server 
defrun(self):# 进入监听状态 
while1:                                        # 使用while循环等待连接 
try:                                        # 捕获异常 
                client, addr = self.server.accept()     # 等待连接 
                self.edit.insert(tkinter.END,           # 向文本框中输出状态 
'连接来自:%s:%d\n' % addr) 
                data = client.recv(1024)                # 接收数据 
                self.edit.insert(tkinter.END,           # 向文本框中输出数据 
'收到数据:%s \n' % data) 
                client.send(str('I GOT: %s' % data).encode())   # 发送数据 
                client.close()                          # 关闭同客户端的连接 
                self.edit.insert(tkinter.END,           # 向文本框中输出状态 
'关闭客户端\n') 
except:                                     # 异常处理 
                self.edit.insert(tkinter.END,           # 向文本框中输出状态 
'关闭连接\n') 
break# 结束循环 

classControl(threading.Thread):# 控制线程 
def__init__(self, edit):
        threading.Thread.__init__(self) 
        self.edit = edit                                # 保存窗口中的多行文本框 
        self.event = threading.Event()                  # 创建Event对象 
        self.event.clear()                              # 清除event标志 
defrun(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                                                                      # 创建socket连接 
        server.bind(('', 1051))                         # 绑定本机1051端口 
        server.listen(1)                                # 开始监听 
        self.edit.insert(tkinter.END,'正在等待连接\n')    # 向文本框中输出状态 
        self.lt = ListenThread(self.edit,server)        # 创建监听线程对象 
        self.lt.setDaemon(True) 
        self.lt.start()                                 # 执行监听线程 
        self.event.wait()                               # 进入等待状态 
        server.close()                                  # 关闭连接 
defstop(self):# 结束控制进程 
        self.event.set()                                # 设置event标志 

classWindow:# 主窗口 
def__init__(self, root):
        self.root = root 
        self.butlisten = tkinter.Button(root,           # 创建组件 
                text = '开始监听', command = self.Listen) 
        self.butlisten.place(x = 20, y = 15) 
        self.butclose = tkinter.Button(root, 
                text = '停止监听', command = self.Close) 
        self.butclose.place(x = 120, y = 15) 
        self.edit = tkinter.Text(root) 
        self.edit.place(y = 50) 
defListen(self):# 处理按钮事件 
        self.ctrl = Control(self.edit)                  # 创建控制线程对象 
        self.ctrl.setDaemon(True) 
        self.ctrl.start()                               # 执行控制线程 
defClose(self):
        self.ctrl.stop()                                # 结束控制线程 
root = tkinter.Tk() 
window = Window(root) 
root.mainloop() 

客户端程序

#-*- coding:utf-8 -*- 
#file: client.py 
#
import tkinter 
import socket 
classWindow:
def__init__(self, root):# 创建组件 
        label1 = tkinter.Label(root, text = 'IP') 
        label2 = tkinter.Label(root, text = 'Port') 
        label3 = tkinter.Label(root, text = 'Data') 
        label1.place(x = 5, y = 5) 
        label2.place(x = 5, y = 30) 
        label3.place(x = 5, y = 55) 
        self.entryIP = tkinter.Entry(root) 
        self.entryIP.insert(tkinter.END, '127.0.0.1') 
        self.entryPort = tkinter.Entry(root) 
        self.entryPort.insert(tkinter.END, '1051') 
        self.entryData = tkinter.Entry(root) 
        self.entryData.insert(tkinter.END, 'Hello') 
        self.Recv = tkinter.Text(root) 
        self.entryIP.place(x = 40, y = 5) 
        self.entryPort.place(x = 40, y = 30) 
        self.entryData.place(x = 40, y = 55) 
        self.Recv.place(y = 115) 
        self.send = tkinter.Button(root, text = '发送数据', command = self.Send) 
        self.send.place(x = 40, y = 80) 
defSend(self):# 按钮事件 
try:                                                # 异常处理 
            ip = self.entryIP.get()                         # 获取IP 
            port = int(self.entryPort.get())                # 获取端口 
            data = self.entryData.get()                     # 获取发送数据 
            client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                                                                      # 创建socket对象 
            client.connect((ip,port))                       # 连接服务端 
            client.send(data)                               # 发送数据 
            rdata = client.recv(1024)                       # 结束数据 
            self.Recv.insert(tkinter.END, 'Server:' + rdata .decode() + '\n')                                                               # 输出接受的数据 
            client.close()                                  # 关闭连接 
except : 
            self.Recv.insert(tkinter.END, '发送错误\n') 
root = tkinter.Tk() 
window = Window(root) 
root.mainloop() 

传送文件

服务端程序

#-*- coding:utf-8 -*- 
#file: FileServer.py 
#
import tkinter 
import threading 
import socket 
import os 
classListenThread(threading.Thread):# 创建监听线程 
def__init__(self,edit,server):
        threading.Thread.__init__(self) 
        self.edit = edit                                # 保存窗口中的多行文本框 
        self.server = server 
        self.file = 'receive.txt'
defrun(self):# 进入监听状态 
while1:                                        # 使用while循环不停监听 
try:                                        # 捕获异常 
                self.client, addr = self.server.accept()    # 等待连接 
                self.edit.insert(tkinter.END,           # 向文本框中输出状态 
'连接来自:%s:%d\n' % addr) 
                self.edit.insert(tkinter.END,           # 向文本框中输出数据 
'开始接收数据:') 
                file = os.open(self.file, os.O_WRONLY|os.O_CREAT    # 创建文件 
                        |os.O_EXCL|os.O_BINARY) 
while1: 
                    rdata = self.client.recv(1024)      # 接受数据 
ifnot rdata: 
break
                    os.write(file,rdata)                # 将数据写入文件 
                    self.edit.insert(tkinter.END,'......') # 向文本框中输出进度 
                os.close(file)                          # 关闭文件 
                self.client.close()                     # 关闭与客户端的连接 
                self.edit.insert(tkinter.END,           # 向文本框中输出状态 
'\n接收完毕,关闭客户端\n') 
except:                                     # 异常处理 
                self.edit.insert(tkinter.END,           # 向文本框中输出状态 
'\n网络错误,关闭连接\n') 
break# 结束循环 

classControl(threading.Thread):# 控制线程 
def__init__(self, edit):
        threading.Thread.__init__(self) 
        self.edit = edit                                # 保存窗口中的多行文本框 
        self.event = threading.Event()                  # 创建Event对象 
        self.event.clear()                              # 清除event标志 
defrun(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)      # 创建socket连接 
        server.bind(('', 1051))                         # 绑定本机1051端口 
        server.listen(1)                                # 开始监听 
        self.edit.insert(tkinter.END,'正在等待连接\n')    # 向文本框中输出状态 
        self.lt = ListenThread(self.edit,server)        # 创建监听线程对象 
        self.lt.setDaemon(True) 
        self.lt.start()                                 # 执行监听线程 
        self.event.wait()                               # 进入等待状态 
        server.close()                                  # 关闭连接 
defstop(self):# 结束控制进程 
        self.event.set()                                # 设置event标志 

classWindow:# 主窗口 
def__init__(self, root):
        self.root = root 
        self.butlisten = tkinter.Button(root,           # 创建组件 
                text = '开始监听', command = self.Listen) 
        self.butlisten.place(x = 20, y = 15) 
        self.butclose = tkinter.Button(root, 
                text = '停止监听', command = self.Close) 
        self.butclose.place(x = 120, y = 15) 
        self.edit = tkinter.Text(root) 
        self.edit.place(y = 50) 
defListen(self):# 处理按钮事件 
        self.ctrl = Control(self.edit)                  # 创建控制线程对象 
        self.ctrl.setDaemon(True) 
        self.ctrl.start()                               # 执行控制线程 
defClose(self):
        self.ctrl.stop()                                # 结束控制线程 
root = tkinter.Tk() 
window = Window(root) 
root.mainloop() 

客户端程序

#-*- coding:utf-8 -*- 
#file: FileClient.py 
#
import tkinter 
import tkinter.filedialog 
import socket 
import os 
classWindow:
def__init__(self, root):# 创建组件 
        label1 = tkinter.Label(root, text = 'IP') 
        label2 = tkinter.Label(root, text = 'Port') 
        label3 = tkinter.Label(root, text = '文件') 
        label1.place(x = 5, y = 5) 
        label2.place(x = 5, y = 30) 
        label3.place(x = 5, y = 55) 
        self.entryIP = tkinter.Entry(root) 
        self.entryIP.insert(tkinter.END, '127.0.0.1') 
        self.entryPort = tkinter.Entry(root) 
        self.entryPort.insert(tkinter.END, '1051') 
        self.entryData = tkinter.Entry(root) 
        self.entryData.insert(tkinter.END, 'Hello') 
        self.entryIP.place(x = 40, y = 5) 
        self.entryPort.place(x = 40, y = 30) 
        self.entryData.place(x = 40, y = 55) 
        self.send = tkinter.Button(root, text = '发送文件', command = self.Send) 
        self.openfile = tkinter.Button(root, text = '浏览', command = self.Openfile) 
        self.send.place(x = 40, y = 80) 
        self.openfile.place( x = 170, y = 55) 
defSend(self):# 按钮事件 
try:                                            # 异常处理 
            ip = self.entryIP.get()                     # 获取IP 
            port = int(self.entryPort.get())            # 获取端口 
            filename = self.entryData.get()             # 获取发送数据 
            tt = filename.split('/') 
            name = tt[len(tt)-1] 
            client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)            # 创建socket对象 
            client.connect((ip,port))                   # 连接服务端 
            client.send(name.encode())                  # 发送文件名 

            file = os.open(filename, os.O_RDONLY | os.O_EXCL|os.O_BINARY)                        # 打开文件 
while1:                                    # 发送文件 
                data = os.read(file,1024) 
ifnot data: 
break
                client.send(data) 
            os.close(file)                              # 关闭文件 
            client.close()                              # 关闭连接 
except Exception as e : 
            print('发送错误',e) 
defOpenfile(self):
        r = tkinter.filedialog.askopenfilename(title = 'Python tkinter',    # 创建打开文件对话框 
            filetypes=[('All files', '*'),('Python', '*.py *.pyw')]) 
if r: 
            self.entryData.delete(0, tkinter.END) 
            self.entryData.insert(tkinter.END, r) 

root = tkinter.Tk() 
window = Window(root) 
root.mainloop() 

最新文章

随机文章