你的第一个C/S程序

目录

  • socket
  • 服务端代码
  • 客户端代码
  • 执行结果

socket

socket基础知识

服务端代码

import socket
import threading
import time

MSG_LENGTH = 64
DISCONNECTED = '!CONNECTION CLOSED'
connections = 0

#定义服务器地址
server_ip = socket.gethostbyname(socket.gethostname())
server_port = 5555
server_addr = (server_ip, server_port)

#创建服务器套接字并绑定到工作地址
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(server_addr)

def handle_client(client_socket, client_addr):
    print(f'新连接建立,远程客户机地址是:{client_addr}'+'\n')
    connected = True
    while connected:
        try:
            msg_len = client_socket.recv(MSG_LENGTH).decode('utf-8') #接收消息长度
        except ConnectionResetError:
            global connections
            connections -= 1
            print(f'远程客户机{client_addr}关闭了连接,活动连接数量是:{connections}')
            break;
        msg_len = int(msg_len)
        if msg_len > 0:
            msg = client_socket.recv(msg_len).decode('utf-8') # 接收消息内容
            if msg == DISCONNECTED: # 收到客户机断开连接的消息
                connected = False
                print(f'客户机:{client_addr}断开了连接!')
                connections -= 1
                print(f'服务器当前活动连接数量是:{connections}')
            print(f'来自客户机{client_addr}的消息是:{msg}')
            # 回送消息
            echo_message = f'服务器{client_socket.getsockname()}收到消息:{msg},时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}'
            client_socket.send(echo_message.encode('utf-8'))
    client_socket.close() # 关闭会话连接

server_socket.listen()
print(f'服务器开始在{server_addr}侦听...')

while True:
    new_socket, new_addr = server_socket.accept()
    client_thread = threading.Thread(target=handle_client, args=(new_socket, new_addr))
    client_thread.start()
    connections += 1
    print(f'服务器当前活动连接数量是:{connections}')

客户端代码

import socket

MSG_LENGTH = 64
DISCONNECTED = '!CONNECTION CLOSED'

remote_ip = socket.gethostbyname(socket.gethostname())
remote_port = 5555
remote_addr = (remote_ip, remote_port)

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(remote_addr)
print(f'客户机工作地址:{client_socket.getsockname()}')

def send_recv(msg):
    message = msg.encode('utf-8') # 消息编码 发消息需编码
    msg_len = len(message) # 消息长度
    str_len = str(msg_len).encode('utf-8') # 长度编码
    str_len += b' ' * (MSG_LENGTH - len(str_len)) # 空白处补空格
    client_socket.send(str_len) # 发送消息长度
    client_socket.send(message) # 发送消息内容
    echo_message = client_socket.recv(1024).decode('utf-8') # 接收服务器消息
    print(echo_message)

while True:
    inputStr = input('请输入待发送的字符串(Q:结束会话):')
    if inputStr.lower() == 'q':
        break
    send_recv(inputStr) # 发送消息和接收消息

send_recv(DISCONNECTED)
client_socket.close()

执行结果

启动服务端:
在这里插入图片描述

启动客户端1并发送消息:
在这里插入图片描述
在这里插入图片描述

启动客户端2并发送消息:
在这里插入图片描述
在这里插入图片描述

启动客户端3并发送消息:
在这里插入图片描述

在这里插入图片描述

关闭客户机2:
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/290716.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

三城三奖!苏州金龙助力各地公共交通打造高品质线路

元旦前夕,由中国交通报社主办的绿色运输可持续发展座谈会暨2023年度“新能源公交高品质线路”经验交流会在京举行,来自全国各地的100余名行业管理部门、公交客运企业代表参会。会上同时评选出20条各具特色的“新能源公交高品质线路”及6家“我的公交我的…

后端主流框架-SpringMvc-day2

Java中的文件下载 2 文件下载 文件下载:就是将服务器(表现在浏览器中)中的资源下载(复制)到本地磁盘; 2.1 前台代码 前台使用超链接,超链接转到后台控制器,在控制器通过流的方式…

阿里云服务器(ECS云服务器)安装redis

前言: 笔者使用的是云服务器是阿里云的ECS服务器 这个服务器内核是Alibaba Cloud Linux 3。 使用的命令行工具为Alibaba Could Manager 命令行工具连接服务器这里就不多说了,如果没有用过的小伙伴可以去看阿里云的官方文档,很详细。 下面…

【51单片机系列】LCD1602液晶模块

本文是关于液晶显示屏的相关介绍。相对于静态数码管、动态数码管、LED点阵等,LCD1602液晶显示器能够显示更多的字符数字信息,并且也是常用的一种显示装置。 文章目录 一、LCD1602介绍1.1、LCD1602简介1.2、LCD1602常用指令1.3、LCD1602使用 二、LCD1602使…

[雷池WAF]长亭雷池WAF配置基于健康监测的负载均衡,实现故障自动切换上游服务器

为了进一步加强内网安全,在原有硬WAF的基础上,又在内网使用的社区版的雷池WAF,作为应用上层的软WAF。从而实现多WAF防护的架构。 经过进一步了解,发现雷池WAF的上游转发代理是基于Tengine的,所以萌生出了一个想法&…

SpringMVC-获取请求参数

1. 通过ServletAPI获取请求参数 /**** param request HttpServletRequest对象,直接作为形参传入方法,前端处理器就是一个Servlet* 所以前端处理器可以获得HttpServletRequest对象,并根据控制器方法的形参将对象传递给方法* re…

勒索事件急剧增长,亚信安全发布《勒索家族和勒索事件监控报告》

近期(12.15-12.21)态势快速感知 近期全球共发生了247起攻击和勒索事件,勒索事件数量急剧增长。 近期需要重点关注的除了仍然流行的勒索家族lockbit3以外,还有本周top1勒索组织toufan。toufan是一个新兴勒索组织,本周共发起了108起勒索攻击&a…

一文读懂$mash 通证的 “Fair Launch” 规则,将公平发挥极致

Solmash 是Solana生态中由社区主导的铭文资产LaunchPad平台,该平台旨在为Solana原生铭文项目,以及通过其合作伙伴SoBit跨链桥桥接到Solana的Bitcoin生态铭文项目提供更广泛的启动机会。有了Solmash,将会有更多的Solana生态的铭文项目、资产通…

【JUC的四大同步辅助类】

文章目录 一、CountDownLatch二、CyclicBarrier三、Semaphore四、Phaser 提示:以下是本篇文章正文内容,下面案例可供参考 一、CountDownLatch CountDownLatch如同火箭发射,计数只能不断减减,当到达0时即发射 场景示例&#xff1…

elect函数可以设置等待时间,

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,贝叶斯滤波与Kalman估计、多传感器信息融合,机器学习,人工智能&#xff0c…

ssm基于BS的仓库在线管理系统的设计与实现论文

摘 要 如今的时代,是有史以来最好的时代,随着计算机的发展到现在的移动终端的发展,国内目前信息技术已经在世界上遥遥领先,让人们感觉到处于信息大爆炸的社会。信息时代的信息处理肯定不能用之前的手工处理这样的解决方法&#x…

OpenCV-Python(23):傅里叶变换

原理 傅里叶变换是一种数学变换,用于将一个函数(在图像处理中通常是图像)从时域(空域)转换到频域。它将函数表示为一系列正弦和余弦函数的和,用于分析信号的频率和相位信息。 傅里叶变换的原理是将一个连续…

【iOS安全】JS 调用Objective-C中WKWebview Handler的三种方式

有三种实现途径 1. WKScriptMessageHandler OC部分:注册并实现Handler 将OC中的方法"nativeMethod"注册为JavaScript Message Handler,从而WebView中的JavaScript代码可以调用该方法 // Register in Objective-C code - (void)setupWKWebVi…

No Magic—复杂机电产品系统架构开发套件

产品概述 CATIA Magic,原名MagicDraw,俗称No Magic,被达索收购后融入3DExperience产品协同研发管理平台中,形成更具协同体验的系统工程解决方案。该软件提供对SysML/UML/UAF语言的完整支持,提供独有的MagicGrid方法论&…

5分钟了解接口测试

接口测试是指对系统接口进行测试的一种质量保障手段,主要是验证接口的功能、性能、安全性等方面是否符合预期。 在接口测试中,可以测试以下内容: 功能测试:验证接口的输入和输出是否符合预期,包括参数的正确性、返回结…

【无标题】idea的lombok插件支持@SuperBuilder注解啦

在我的博客阅读本文 1. 前言 今早进公司打开idea,弹出更新提示,简单看了下,原来是idea的lombok插件更新了,惊喜的发现update log上写着Add support for SuperBuilder。 为什么说是惊喜呢?因为之前也有用到这个的场景…

Go后端开发 -- Go Modules

Go后端开发 – Go Modules 文章目录 Go后端开发 -- Go Modules一、什么是Go Modules?二、GOPATH的工作模式1.GOPATH模式2.GOPATH模式的弊端 三、Go Modules模式创建项目1.go mod命令2.go mod环境变量3.使用Go Modules初始化项目4.修改模块的版本依赖关系 四、Go Modules下impo…

数据库:基础SQL知识+SQL实验2

(1)基础知识: 1.JOIN(连接): 连接操作用于根据指定的条件将两个或多个表中的数据行合并在一起。JOIN 可以根据不同的条件和方式执行,包括等值连接、不等值连接等。 (1&#xff09…

SAP BAPI 客户主数据创建:cmd_ei_api=>maintain_bapi

BAPI函数:cmd_ei_api>maintain_bapi 事物代码:XD01/XD02 客户主数据创建、修改、拓展功能开发 数据结构定义: 基本视图信息 公司代码信息结构: 销售视图信息结构: 客户主数据税分类信息结构: 代码参考 详细代码…

C++面向对象编程与泛型编程(GP)

C既支持面向对象编程,又支持泛型编程 1.面向对象编程 将数据结构与处理方法(容器与算法)组成对象封装在一个类中,通过类的封装隐藏内部细节,可以使用继承,多态等方法。 注意:list容器本身带有…