TCP通信Socket编程----传输不同数据类型。

更新记录】:2021.12.29、

TCP通信传输字符串和浮点数。

作业题目说明:“实现基于TCP的socket通信,完成字符串、浮点数据的传输。”

mine_:我之前是想直接将用户输入的传过去就行了,但这样其实就是字符串形式传输了。而题目希望我们分别传输字符串和浮点数这两种格式,最终在网络中都是以字节形式传输,但是对于数据处理的方法不同。还有一个核心考察点就是需要思考粘包问题,即需要运用封包技术。python中一个浮点数的字节是4个字节,是固定的。而字符串的字节就不固定了。
mine_下次改进】:还有哪些封包技术?如何运用?深刻理解sendall()和recv()函数底层原理。dai对于socket底层要做一下总结。

#!/usr/bin/env python3
# coding=utf-8

from socket import *
import struct


class TcpClient(object):
    """
    题目要求:实现基于TCP的socket通信,完成字符串、浮点数据的传输。
    代码功能简述:客户端输入浮点数,然后传送给服务端,服务端再返回给客户端并打印,以实现echo功能,本代码重点处在于,为了防止粘包现象,先传输4字节的包,告诉服务端将要传输过来的数据的大小,以保证它能完整接受这一次的数据,然后再返回给客户端,客户端同样要用检查已收到的数据包的大小保证不粘包。
    代码中存在的疑问点:浮点数传过去13.4 真实输出的却不是13.4,而是一个不是13.4但很接近13.4d的多位浮点数,不知为啥。
    Tcp客户端
  
    """
    def __init__(self, server_ip, server_port):
        """初始化对象"""
        self.code_mode = "utf-8"    #收发数据编码/解码格式
        self.server_ip = server_ip
        self.server_port =server_port
        self.my_socket = socket(AF_INET, SOCK_STREAM)   #创建socket
    def get_input_float(self):
        '''要求用户输入一个浮点数
        '''
        while True:
            try:
                float_message=float(input())
            except ValueError:
                print('请输入一个浮点数')
                continue
            else:
                return float_message
                break

    def tcp_send_float(self):
        while True:
            print('请输入一个浮点数(输入0退出)')
            float_message=self.get_input_float()
            if float_message==0:
                break
            self.my_socket.sendall(struct.pack('i',4))# 将数据长度发过去
            self.my_socket.sendall(struct.pack('f',float_message))
            received_bytes=0
            message_received=b''
            while received_bytes<4:
                message_received+=self.my_socket.recv(4)
                received_bytes+=len(message_received)
            echo_float=struct.unpack('f',message_received)[0]
            print("%.1f"%echo_float)


    def tcp_send_string(self):
        while True:
            string_message=input('请输入一个字符串(输入exit退出)')
            if string_message=='exit':
                break
            self.my_socket.sendall(struct.pack('i',len(string_message)))# 将数据长度发过去
            self.my_socket.sendall(string_message.encode(self.code_mode))
            print('发去的数据长度',len(string_message))
            message_received=b''
            while len(message_received)<len(string_message):
                received=self.my_socket.recv(4)
                message_received+=received
            print(message_received.decode(self.code_mode))
            


    def run(self):
        """启动"""
        self.my_socket.connect((self.server_ip, self.server_port))  #连接服务器
        print('此程序为:测试TCP传输中的浮点数传输')
        self.tcp_send_float()
        print('此程序为:测试TCP传输中的字符串传输')

        self.tcp_send_string()
        self.my_socket.close()






if __name__ == "__main__":
    #server_ip = input("请输入服务器IP:")
    #server_port = int(input("请输入服务器Port:"))
    my_socket = TcpClient('127.0.0.1', 8070)
    my_socket.run()
#!/usr/bin/env python3
# coding=utf-8

from socket import *
import struct

class TcpServer(object):
    """
    实现基于TCP的socket通信,完成字符串、浮点数据的传输。
    题目要求:实现基于TCP的socket通信,完成字符串、浮点数据的传输。
    代码功能简述:客户端输入浮点数,然后传送给服务端,服务端再返回给客户端并打印,以实现echo功能,本代码重点处在于,为了防止粘包现象,先传输4字节的包,告诉服务端将要传输过来的数据的大小,以保证它能完整接受这一次的数据,然后再返回给客户端,客户端同样要用检查已收到的数据包的大小保证不粘包。
    代码中存在的疑问点:浮点数传过去13.4 真实输出的却不是13.4,而是一个不是13.4但很接近13.4d的多位浮点数,不知为啥。
    Tcp服务端"""
    def __init__(self, port):
        """初始化对象"""
        self.code_mode = "utf-8"    #收发数据编码/解码格式
        self.server_socket = socket(AF_INET, SOCK_STREAM)   #创建socket
        self.server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)   #设置端口复用
        self.server_socket.bind(("", port))     #绑定IP和Port
        self.server_socket.listen(100)  #设置为被动socket
        print("Listen...")

    def run(self):
        """运行"""
        while True:
            client_socket, client_addr = self.server_socket.accept()
            print("{} online".format(client_addr))
            while True:
                header=client_socket.recv(4)
                if not header:
                    break
                message_len=struct.unpack('i',header)[0]
                print('发来的又返回去的数据字节长度是',message_len)
                received_message=b''
                while len(received_message)<message_len:
                    received=client_socket.recv(4)
                    received_message+=received
                client_socket.sendall(received_message)
            print("{} offline".format(client_addr))
            client_socket.close()


if __name__ == "__main__":
    #port = int(input("请输入要绑定的Port:"))
    my_server = TcpServer(8070)
    my_server.run()

代码测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
etn004_socket_tcpsend是欧姆龙PLC(可编程逻辑控制器)中一个功能块,用于实现TCP/IP协议的数据发送功能。以下是一个使用该功能块的实例子: 假设我们的PLC需要通过以太网连接一个远程的服务器,并向其发送一条包含温度数据的信息。首先,我们需要进行以下准备工作: 1. 确保PLC和服务器在同一个局域网下,并且已经正确设置了网络参数。 2. 创建一个变量,用于存储TCP/IP通信的控制参数。我们可以使用一个数组来存储这些参数,比如定义一个名为"TCP_Param"的数组,长度为10,用来存储IP地址、端口号等相关信息。 3. 定义一个变量,用于存储需要发送的数据。比如定义一个名为"Send_Data"的变量,类型为字符串。 接下来,我们可以使用etn004_socket_tcpsend功能块来实现数据发送。假设我们将该功能块的实例化命名为"S_TcpSend",使用时可以按照以下步骤进行: 1. 将需要发送的数据存储到"Send_Data"变量中,可以通过其他程序块或传感器获取到数据并进行赋值。 2. 设置TCP/IP通信的控制参数。假设我们要连接的服务器IP地址为192.168.0.100,端口号为5000,可以通过设置"TCP_Param"数组的元素来进行设置,如"TCP_Param[0]:=192.168.0.100","TCP_Param[1]:=5000"。 3. 调用etn004_socket_tcpsend功能块进行数据发送。在程序中调用"S_TcpSend",并将"Send_Data"和"TCP_Param"作为输入参数传入,如"S_TcpSend(Send_Data, TCP_Param)"。 当以上步骤完成后,PLC将会通过TCP/IP协议向目标服务器发送包含温度数据的信息,并等待服务器的响应。 需要注意的是,在实际使用中,还需要进行异常处理、连接状态判断等操作,以保证数据的正常发送和接收。 以上就是一个简单的etn004_socket_tcpsend功能块的使用实例子。实际应用中,我们可以根据具体的需求进行参数的设置和数据的发送,来实现灵活的TCP/IP通信

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Abner_iii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值