python中的tcp示例详解

Python中的TCP示例详解

在Python中,使用TCP/IP协议进行网络通信非常常见。本篇文章将结合两个简单的例子,详细讲解Python中如何使用TCP协议进行通信。

示例一:客户端与服务端的基本交互

首先,我们需要了解socket模块。在Python中,socket模块提供了构建网络应用程序所需的基础设施。具体可以通过以下代码引入socket模块:

import socket

接下来,我们将创建一个简单的客户端程序,连接到指定的服务器。客户端会发送一条消息给服务器,然后等待服务器的回复。以下是基本示例代码:

import socket

HOST = 'localhost'
PORT = 8888

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b'Hello, world')
    data = s.recv(1024)

print('Received', repr(data))

在以上代码中,socket.AF_INET表示使用IPv4协议,socket.SOCK_STREAM表示使用流式TCP协议。s.connect((HOST, PORT))方法表示连接到指定的服务器,端口号为8888。s.sendall(b'Hello, world')表示向服务器发送一条消息。接着,客户端等待服务器的回复,收到消息后将其打印出来。

接下来,我们将创建一个简单的服务器程序,接收客户端的消息并给出回复。以下是基本示例代码:

import socket

HOST = 'localhost'
PORT = 8888

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()
    with conn:
        print('Connected by', addr)
        while True:
            data = conn.recv(1024)
            if not data:
                break
            conn.sendall(data)

在以上代码中,s.bind((HOST, PORT))方法表示指定服务器的IP地址和端口号。s.listen(1)表示监听客户端的请求,最大允许连接数为1。conn, addr = s.accept()方法表示等待客户端的连接请求,然后建立连接。conn.recv(1024)方法表示接收客户端发送的消息,conn.sendall(data)方法表示向客户端发送回复消息。当客户端没有发送消息时,服务端程序退出循环。

以上代码可通过使用python3命令运行,模拟客户端和服务端进行简单的交互。

示例二:使用Python实现聊天室

假设你需要实现一个简单的聊天室,可以通过以下示例代码实现。

import socket
import threading

class Server:
    def __init__(self, host, port):
        self.host = host
        self.port = port
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server_socket.bind((self.host, self.port))
        self.server_socket.listen(5)
        self.clients = []

    def broadcast(self, message, sender):
        for client in self.clients:
            if client != sender:
                client.send(message)

    def handle(self, client):
        while True:
            try:
                message = client.recv(1024)
                if message:
                    message = "{}: {}".format(client.getpeername(), message.decode())
                    print(message)
                    self.broadcast(message, client)
                else:
                    self.remove(client)
            except:
                self.remove(client)
                break

    def remove(self, client):
        if client in self.clients:
            self.clients.remove(client)

    def run(self):
        print("Server started on {}:{}".format(self.host, self.port))

        while True:
            client, address = self.server_socket.accept()
            print("{} connected.".format(str(address)))
            self.clients.append(client)
            client.send("Welcome to the chatroom! Please enter your name.".encode())
            thread = threading.Thread(target=self.handle, args=(client,))
            thread.daemon = True
            thread.start()

class Client:
    def __init__(self, host, port, name):
        self.host = host
        self.port = port
        self.name = name
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    def connect(self):
        self.sock.connect((self.host, self.port))

    def send_message(self, message):
        self.sock.sendall("{}: {}".format(self.name, message).encode())

    def receive_message(self):
        while True:
            try:
                message = self.sock.recv(1024)
                if message:
                    print(message.decode())
            except:
                print("Error Occured.")
                self.sock.close()
                break

if __name__ == "__main__":
    mode = input("Enter 's' for Server, 'c' for Client: ")
    if mode == "s":
        server = Server("localhost", 8888)
        server.run()
    else:
        client_name = input("Enter your name: ")
        client = Client("localhost", 8888, client_name)
        client.connect()

        receive_thread = threading.Thread(target=client.receive_message)
        receive_thread.daemon = True
        receive_thread.start()

        while True:
            message = input()
            if message.lower() == 'quit':
                break
            client.send_message(message)

以上代码可以通过以下两种方法运行:

  1. 作为服务器程序运行:在终端输入python3 chatroom.py并按回车键,然后输入s,即可将Python程序作为服务器程序运行。
  2. 作为客户端程序运行:在终端输入python3 chatroom.py并按回车键,则进入客户端模式,可以输入用户名并进行聊天。在聊天过程中,可以随时在命令行输入'quit'退出程序。

以上述代码为基础,你还可以添加更多的功能,来实现更完善的聊天室应用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python中的tcp示例详解 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • 魔兽世界7.3.5奶德怎么堆属性 wow7.35奶德配装属性优先级攻略

    魔兽世界7.3.5奶德怎么堆属性 在7.3.5版本中,奶德主要的属性是精通和急速。对于奶德来说,精通是提高治疗效果最优先的属性,急速则是提高施法速度和瞬发技能的重要属性。 奶德配装属性优先级攻略 奶德的衣服和配饰属性会对治疗效果产生重大影响,因此配装方案十分重要。 1. 保持高精通 精通对于奶德来说是最重要的属性,可以提高治疗效果。因此在装备选择上,应该优先…

    other 2023年6月27日
    00
  • Go Web 编程中的模板库应用指南(超详细)

    Go Web 编程中的模板库应用指南(超详细) 本攻略将详细介绍在 Go Web 编程中如何使用模板库。模板库是一种用于生成动态内容的工具,它可以将数据和静态模板结合起来,生成最终的 HTML 页面。在 Go 中,我们可以使用多个模板库,如 html/template 和 text/template。 1. 安装模板库 首先,我们需要安装 Go 的模板库。在…

    other 2023年8月6日
    00
  • Mysql大小写敏感的问题

    MySQL大小写敏感的问题攻略 MySQL是一个常用的关系型数据库管理系统,它在处理大小写时有一些敏感性。本攻略将详细讲解MySQL大小写敏感的问题,并提供两个示例说明。 1. MySQL的大小写敏感性 MySQL在处理标识符(如表名、列名、变量名等)时,根据配置的不同,可能会对大小写敏感或不敏感。这取决于以下两个因素: 操作系统:在某些操作系统上,文件系统…

    other 2023年8月15日
    00
  • windows server2012域分发APP应用程序的方法

    下面是详细讲解“Windows Server 2012域分发APP应用程序的方法”的完整攻略: 步骤一:创建应用包 打开开发工具(如Visual Studio),创建一个UWP项目。 完成项目的开发、测试和打包,生成.appxbundle文件和证书文件。 步骤二:上传应用包 打开Windows Dev Center,登录自己的开发者账号。 选择“应用管理”→…

    other 2023年6月25日
    00
  • intellij idea全局查找和替换的具体使用

    IntelliJ IDEA全局查找和替换的具体使用攻略 IntelliJ IDEA是一款功能强大的集成开发环境(IDE),提供了全局查找和替换功能,可以帮助开发者快速定位和替换代码中的特定内容。下面是使用IntelliJ IDEA全局查找和替换的详细步骤和示例说明。 步骤1:打开全局查找和替换窗口 在IntelliJ IDEA中,你可以通过以下步骤打开全局查…

    other 2023年8月19日
    00
  • 网络安全渗透测试反序列化漏洞分析与复现工作

    很抱歉,由于当前平台的限制,我无法以标准的markdown格式文本回答您的问题。但是,我可以为您提供详细的攻略,包含两个示例说明。以下是关于网络安全渗透测试反序列化漏洞分析与复现工作的完整攻略: 1. 反序列化漏洞分析 反序列化漏洞是一种常见的安全漏洞,攻击者可以利用该漏洞执行恶意代码。以下是反序列化漏洞分析的步骤: 确定目标:选择要分析的应用程序或系统。 …

    other 2023年10月19日
    00
  • 增强Linux内核中访问控制安全的方法

    当访问控制不足时,攻击者可能会利用系统漏洞或者僵尸进程进行系统内部攻击。在Linux系统中,内核是最基础也是最核心的部分。因此,Linux内核的安全性至关重要。本文将讲述如何增强Linux内核中的访问控制安全。 1.使用命名空间隔离系统资源 使用命名空间技术隔离系统资源,能够使容器得到隔离并提供安全的容器内环境。在Linux3.8版本中,引入了六种命名空间类…

    other 2023年6月27日
    00
  • c里面的static inline函数

    C里面的static inline函数 在C语言中,我们可以使用static关键字和inline关键字来定义函数。那么,当我们把两者一起使用时,会出现什么情况呢?本文将详细讨论C语言中的static inline函数。 static关键字的作用 在C语言中,static关键字有两种用途。一是用于局部变量,表示该变量的作用域仅限于当前代码块;二是用于全局变量和…

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部