Skip to main content

Python 入门基础知识 - socket建立客户端和服务端

Python 入门基础知识 - socket建立客户端和服务端

socket建立客户端和服务端

1,建立服务端

使用socket模块建立一个简单的服务端。首先应创建一个socket对象,使用socket对象的bind方法绑定IP地址和端口。

然后使用socket对象的listen方法监听socket连接。最后进入循环等待客户端的连接。代码如下

# -*- coding: utf-8 -*-
import Tkinter
import threading
import socket


class ListenThread(threading.Thread):  # 监听线程

    def __init__(self, edit, server):
        threading.Thread.__init__(self)
        self.edit = edit  # 保存窗口中的多行文本框
        self.server = server

    def run(self):  # 进入监听状态
        while 1:  # 使用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('I GOT: %s' % data)  # 发送数据
                client.close()  # 关闭同客户端的连接
                self.edit.insert(Tkinter.END, '关闭客户端\n')  # 向文本框中输出状态
            except IndexError, value:
                self.edit.insert(Tkinter.END, value)
                self.edit.insert(Tkinter.END, '关闭连接\n')
                break  # 结束循环


class Control(threading.Thread):  # 控制线程

    def __init__(self, edit):
        threading.Thread.__init__(self)
        self.edit = edit  # 保留窗口中的多行文本框
        self.event = threading.Event()  # 创建Event对象
        self.event.clear()  # 清楚event标志

    def run(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()  # 关闭连接

    def stop(self):  # 结束控制线程
        self.event.set()  # 设置event标志


class Window:  # 主窗口

    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)

    def listen(self):  # 处理按钮事件
        self.ctrl = Control(self.edit)  # 创建控制线程对象
        self.ctrl.setDaemon(True)
        self.ctrl.start()  # 执行控制线程

    def close(self):
        self.ctrl.stop()  # 结束控制线程


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

在上面的代码中,由于使用while循环监听连接,为了避免图形界面下假死的状态,将while循环放在一个线程里执行,

但Python中没有提供结束线程的函数或者方法,为了随时终止监听,在脚本中创建了一个控制线程。通过控制线程执行

监听线程,然后控制线程进如等待状态。当event被设置后,在控制线程中将关闭socket连接,监听也就停止了。由于

监听线程已经进入监听状态,在控制线程中关闭socket连接将导致异常,所有在监听线程中使用try捕获异常,结束循环。

2,建立客户端

客户端的创建相对简单,只要连接指定的IP和端口地址,然后想服务器发送数据即可,代码如下

# -*- coding: utf-8 -*-
import Tkinter
import socket


class Window:

    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=105)
        self.send = Tkinter.Button(root, text='发送数据', command=self.send)
        self.send.place(x=40, y=80)

    def send(self):  # 按钮事件
        try:  # 异常处理
            ip = self.entryIP.get()  # 获取IP
            port = self.entryPort.get()  # 获取端口
            data = self.entryData.get()  # 获取发送数据
            client = socket.socket(
                socket.AF_INET, socket.SOCK_STREAM)  # 创建socket对象

            client.connect((ip, int(port)))  # 连接服务器
            client.send(data)  # 发送数据
            rdata = client.recv(1024)  # 接收数据
            self.Recv.insert(Tkinter.END, "Server: " + rdata + '\n')  # 输出接收的数据
            client.close()  # 关闭连接
        except IndexError, value:
            print(value)
            self.Recv.insert(Tkinter.END, '发送错误\n')


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

服务端点击"开始监听"后,启动客户端,点击"发送数据",这样客户端就能跟服务端进行通信了。

对于新手来说这里又用到Tkinter,这个GUI的模块,请关注后面的GUI模块的相关分享

版权声明

版权声明

durban.zhang 创作并维护的 Walkerfree 博客采用 创作共用保留署名-非商业-禁止演绎4.0国际许可证。本文首发于 Walkerfree 博客(http://www.walkerfree.com/),版权所有,侵权必究。本文永久链接:http://www.walkerfree.com/article/89