首页 > 编程语言 >python网络编程---TCP协议进行

python网络编程---TCP协议进行

时间:2024-07-15 20:02:02浏览次数:12  
标签:sk socket python TCP --- 服务器 接字 连接 客户端

        在这里简单实现一个TCP服务器,用于监听来自客户端的连接,接收客户端发送的消息,并向客户端发送响应消息。下面我将详细解释这个代码的工作原理和各个部分的作用。

        首先建立一个客户端(client),一个服务端(server),在客户端进行连接到运行在本地机器(IP地址为127.0.0.1)上的TCP服务器,该服务器监听8080端口。客户端通过标准输入接收用户输入的消息,将这些消息发送给服务器,并接收来自服务器的响应。

client:

  1. 导入必要的模块
    • import socket, json:这里导入了socket模块用于网络通信,同时也导入了json模块,尽管在这个示例中json模块并未被使用。如果客户端和服务器之间需要交换复杂的数据结构(如字典或列表),则可以使用json模块来序列化和反序列化这些数据。
  2. 创建socket套接字
    • sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM):创建了一个socket对象sk,用于IPv4 (AF_INET) 和TCP (SOCK_STREAM) 通信。
  3. 连接到服务器
    • sk.connect(("127.0.0.1", 8080)):客户端通过connect方法连接到服务器的IP地址和端口号。这里使用的是本地回环地址127.0.0.1和端口号8080
  4. 发送和接收消息
    • 客户端进入一个无限循环,等待用户输入消息。
    • 使用input函数获取用户输入的消息,并通过sk.send(msg.encode("utf-8"))将消息编码为UTF-8格式后发送给服务器。
    • 发送消息后,客户端通过sk.recv(10241024)尝试从服务器接收响应。但这里有一个错误:recv方法的参数应该是单个整数,表示要接收的最大字节数。10241024被解释为1024(因为Python会尝试将这样的数字作为整数处理,而10241024超出了int类型的表示范围,但Python会在这里静默地截断它),这显然不是预期的行为。正确的做法应该是指定一个合理的字节数,比如10244096,这取决于您期望接收的消息大小。
    • 接收到的数据通过res.decode("utf-8")解码为UTF-8格式的字符串,并打印出来。
  5. 关闭套接字
    • sk.close():关闭socket连接。然而,在这个示例中,sk.close()被放在了无限循环之外,这意味着它实际上永远不会被执行,因为程序会一直在循环中等待用户输入。在实际情况中,如果您希望在发送完所有消息后关闭连接,您可能需要将sk.close()放在一个能够触发关闭的条件块中,比如一个接收到特定退出消息的分支内,或者在使用了足够长时间后通过其他方式触发关闭。
import socket
# 创建socket套接字


sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接 connect
sk.connect(("127.0.0.1", 8080))

print("链接成功")
while True:
    msg = input("输入要对服务器端说的话:")

    sk.send(msg.encode("utf-8"))
    print("发送成功\n请等待服务器响应……")

    res = sk.recv(1024)

    res1 = res.decode("utf-8")


    print("服务器端说了",res1)



# 关闭套接字 close()
sk.close()

然后建立一个服务端(server)监听本地机器上的8080端口,等待客户端的连接,并与连接的客户端进行双向通信

server:

  1. 导入必要的模块
    • import socket:导入Python的socket模块,用于网络通信。
    • import json:尽管在这个示例中并未使用到json模块,但它通常用于数据的序列化和反序列化,以便在网络中传输复杂的数据结构(如字典、列表等)。
  2. 创建TCP/IP套接字
    • sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM):创建一个socket对象sk,指定使用IPv4 (AF_INET) 和TCP (SOCK_STREAM) 协议。
  3. 绑定套接字到本地地址和端口
    • sk.bind(("127.0.0.1", 8080)):将sk套接字绑定到本地回环地址127.0.0.1的8080端口上。这样,服务器就只能在本地机器上监听该端口上的连接请求。
  4. 监听连接
    • sk.listen():使服务器进入监听状态,准备接受客户端的连接请求。此时,服务器可以处理多个连接请求,但每次只处理一个,直到该连接关闭。
  5. 通知用户服务器已启动
    • print("服务器启动完成,等待连接……"):在控制台上打印一条消息,通知用户服务器已经启动并等待客户端的连接。
  6. 接受客户端连接
    • 服务器进入一个无限循环,不断使用sk.accept()方法等待并接受客户端的连接。accept()方法会阻塞,直到一个连接到达。当连接到达时,它返回一个包含新连接的socket (conn) 和连接客户端的地址 (addr) 的元组。
  7. 与客户端通信
    • 使用conn.recv(1024)从客户端接收最多1024字节的数据,并将其解码为UTF-8格式的字符串。
    • 检查接收到的数据是否为空字符串(""),如果是,则认为客户端已经关闭了连接,并继续循环等待下一个连接。
    • 如果接收到非空字符串,则打印该字符串,表示客户端发送的消息。
    • 使用input()函数从标准输入获取要发送给客户端的消息,并将其编码为UTF-8格式后发送给客户端。
  8. 关闭套接字
    • 需要注意的是,sk.close()被放在了无限循环之外,这意味着它实际上永远不会被执行,因为程序会一直在循环中等待客户端连接。在真实的应用场景中,sk.close()应该被放置在能够确保服务器不再需要接受新连接的位置,比如接收到一个特定的退出命令后,或者在服务器被外部事件(如接收到SIGINT信号)强制关闭时。
    • 然而,对于每个客户端连接,当通信完成后,应该关闭与之关联的conn套接字,以释放资源。在这个示例中,conn.close()应该在发送完消息给客户端之后被调用,但在循环的末尾之前(否则循环将无法继续接受新的连接)。然而,由于这个示例没有实现客户端断开连接的明确检测(除了检查空字符串外),因此在实际应用中可能需要更复杂的逻辑来处理客户端的断开和套接字的关闭。

# 导入socket模块,用于网络连接和通信
import socket
# 导入json模块,可能用于数据的序列化和反序列化,尽管在示例中未使用
import json

# 创建一个TCP/IP socket
sk = socket.socket(family=socket.AF_INET,
                   type=socket.SOCK_STREAM)

# 绑定socket到本地IP地址和端口号,用于监听进来的连接
# 绑定端口 bind()
sk.bind(("127.0.0.1", 8080))

# 开始监听socket,允许进来的连接排队等待处理
# 监听 listen()
sk.listen()

# 通知用户服务器已经启动并等待连接
print("服务器启动完成,等待连接……")

# 进入无限循环,等待客户端连接
while True:
    # 接受一个客户端连接,返回一个新的socket用于与客户端通信
    # 接收连接 accept()
    conn, addr = sk.accept()
    # 通知用户客户端连接成功
    print(f"{addr}连接成功")

    # 从客户端接收数据,假设数据是UTF-8编码的文本
    res = conn.recv(1024)
    res = res.decode("utf-8")

    # 检查客户端是否已断开连接,如果是,则重新开始循环等待下一个客户端
    if res == "":
        print("断开连接")
        continue

    # 打印客户端发送的消息
    else:
        print("客户端说了:", res)

    # 从用户输入获取要发送给客户端的消息
    msg = input("请输入要对客户端说的话:")

    # 将消息编码为UTF-8并发送给客户端
    conn.send(msg.encode("utf-8"))
    # 通知用户消息发送成功,等待客户端响应
    print("发送成功!\n请等待客户端响应……")

# 关闭socket,结束程序
# 关闭套接字  close()
sk.close()

标签:sk,socket,python,TCP,---,服务器,接字,连接,客户端
From: https://blog.csdn.net/W030321/article/details/140447453

相关文章

  • python中的re模块--正则表达式
    正则表达式,又称规则表达式。(英语:RegularExpression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本  re模块作用通过使用正则表达式,可以:测试字符串内的模式。——例如,可以测试输入字符串,以查......
  • 单链表算法 - 链表的中间节点
    .-力扣(LeetCode).-备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界IT名企DreamOffer。https://leetcode.cn/problems/middle-of-the-linked-list/description/思路1: 思路2:代码:/***Definitionforsingly-linkedlist.*struct......
  • 高项-信息化发展知识要点
    1、信息是物质、能量及其属性的标示的集合,是确定性的增加。它以物质介质为载体,传递和反映世界各种事物存在方式、运动状态等的表征。信息不是物质,也不是能力,它以一种普遍形式,表达物质运动规律,在客观世界中大量存在、产生和传递。2、面向管理和支持生产是信息系统的显著......
  • (138)SRAM接口--->(001)基于FPGA实现SRAM接口
    1目录(a)FPGA简介(b)IC简介(c)Verilog简介(d)基于FPGA实现SRAM接口(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电......
  • (137)SRAM接口--->(004)基于FPGA实现SRAM接口
    1目录(a)FPGA简介(b)IC简介(c)Verilog简介(d)基于FPGA实现SRAM接口(e)结束1FPGA简介(a)FPGA(FieldProgrammableGateArray)是在PAL(可编程阵列逻辑)、GAL(通用阵列逻辑)等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电......
  • Python从0到100(三十九):数据提取之正则(文末免费送书)
    前言:零基础学Python:Python从0到100最新最全教程。想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、计算机视觉、机器学习、神经网络以及人工智能相关知......
  • Python从0到100(四十):Web开发简介-从前端到后端(文末免费送书)
    前言:零基础学Python:Python从0到100最新最全教程。想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、计算机视觉、机器学习、神经网络以及人工智能相关知......
  • 全网最最实用--基于Mac ARM 芯片实现操作系统MIT 6.S081-lab3
    文章目录实验三页表一、代码理解1.对于内存布局定义的理解2.对虚拟内存的理解3.对分配和释放物理内存的理解--删除或者分配物理内存为啥不需更改相应的页表?二、Printapagetable1.题目描述2.题目思考3.提交实验三、Akernelpagetableperprocess1.题目描述2.题目......
  • 真题模拟2022CSP-J总结
    T1乘方这个题真的是很简单,就特判一下1的情况,其它情况直接暴力枚举即可考试的时候也是非常快的想到T2解密也比较容易首先我们把ed=(p_i−1)(q_i−1)+1打开变为ed=pq−p−q+1+1将n=pq带入原式得:ed=n−p−q+2那么我们现在有了两个式子:p+q=n-ed+2pq=n如果我......
  • CodeForces - 1485F
    题目大意给定数组\(b\),求有多少\(a\)数组满足\(a_i=b_i\or\\sum\limits_{k=1}^ia_k=b_i\)。分析既然有前缀和,不妨将前缀和计入状态中,设\(dp_{i,j}\)为前\(i\)个前缀和为\(j\)的方案数。考虑两种条件的转移方程。若选第一种,有\(dp_{i,j}=dp_{i-1,j-b_i}\)若......