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'退出程序。

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

阅读剩余 70%

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

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

相关文章

  • linux安装网易云音乐

    以下是“Linux安装网易云音乐的完整攻略”的详细讲解,过程中包含两个示例说明的标准Markdown格式文本: Linux安装网易云音乐完整攻略 网易云音乐是一款非常受欢迎的音乐播放器,支持多种操作系统。本文将介绍何在Linux系统中安装网易云音乐,并提供两个常见的示例。 1. 原理分析 在Linux系统中,可以使用以下方法安装网易云音乐: 下载网易云音乐的…

    other 2023年5月10日
    00
  • jrebel插件安装配置与破解激活(多方案)详细教程

    JRebel插件安装配置与破解激活(多方案)详细教程 JRebel是一款极其常用的Java热部署插件,可以显著提高开发效率。不过,该插件需要购买才能正常使用。下面是JRebel插件安装、配置和破解激活的多种方案。 方案一:使用激活码 首先从官网下载最新版的JRebel插件,解压到本地。 打开解压后的文件夹,将其中的jrebel.jar和lib文件夹复制到你的…

    其他 2023年3月29日
    00
  • thinkphp 表名 大小写 窍门

    ThinkPHP 表名大小写窍门攻略 在 ThinkPHP 中,表名的大小写是一个常见的问题。本攻略将详细讲解如何处理表名的大小写,以确保在使用 ThinkPHP 进行数据库操作时不会出现问题。 1. 数据库配置 首先,确保在 database.php 配置文件中设置了正确的数据库连接信息。在该文件中,你可以找到以下配置项: ‘params’ => […

    other 2023年8月17日
    00
  • .h和.cpp文件的区别(zt)详细介绍

    .h和.cpp文件的区别 在 C++ 中,需要将程序中的函数和变量声明和定义分别写在不同的文件中,而这些文件通常被称为 .h 和 .cpp 文件。本文将详细讲解这两种文件的区别。 .h 文件 .h 文件通常包含程序的声明部分,包括函数及变量的声明。这些内容通常是用于给其他文件提供接口的。通常 .h 文件中的声明并不需要提供具体的实现,而只需要提供其名称、类型…

    other 2023年6月26日
    00
  • HTML5来实现本地文件读取和写入的实现方法

    实现本地文件读取和写入需要使用HTML5中的File API。File API提供了访问本地文件系统的能力,可以读取本地文件的内容并在网页中展示出来,同时也可以在网页上新建或覆盖本地文件。 实现方法如下: 1.读取本地文件内容 要读取本地文件内容,我们需要使用FileReader对象。 示例1:读取本地txt文件并将其内容展示在网页中。 <input …

    other 2023年6月27日
    00
  • vue实现骨架屏的示例

    Vue实现骨架屏的示例攻略 1. 什么是骨架屏? 骨架屏是一种用于优化用户体验的页面加载效果。它会先展示一个简单的页面结构,给用户一种页面正在加载的感觉,同时也提供了一种参照,让用户知道具体内容将要填充到哪个位置上。 2. 实现步骤 2.1 创建Vue项目 首先,我们需要创建一个Vue项目。可以使用Vue CLI来快速搭建项目结构。在命令行中执行以下命令: …

    other 2023年6月28日
    00
  • kafka消费者groupid设置

    kafka消费者groupid设置 在Kafka中,GroupId是一种逻辑概念,用于将消费者归类为一个组。同一组内的多个消费者可以共同消费同一个Topic的数据,并保证每条消息只被组内的一个消费者消费。这是Kafka实现多个消费者同时消费一个Topic的核心机制。 那么如何设置Kafka消费者的GroupId呢? Kafka消费者GroupId的设置 Ka…

    其他 2023年3月28日
    00
  • Android布局控件之常用linearlayout布局

    下面是“Android布局控件之常用LinearLayout布局”的完整攻略。 常用LinearLayout布局 LinearLayout布局简介 LinearLayout布局是Android中最基本、最常用的布局之一,其主要作用是将子控件按照线性方向依次排列。LinearLayout分为水平(horizontal)和垂直(vertical)两种方向,水平方…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部