Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在TCP/IP python中在何处添加编码和解码_Python_Tcp Ip - Fatal编程技术网

在TCP/IP python中在何处添加编码和解码

在TCP/IP python中在何处添加编码和解码,python,tcp-ip,Python,Tcp Ip,我需要从一台笔记本电脑到另一台笔记本电脑发送/接收数据,我使用的是Python3.6,看起来这个版本的python需要.encode()和.decode() 函数,我使用的是Python2.7,以前我没有遇到任何问题,但是现在和Python3.6我必须使用这些函数,但是我不确定应该在哪里使用.decode()命令,您可以在我的服务器文件和客户机文件下面找到 服务器文件: import socket import threading import os def RetrFile(name, so

我需要从一台笔记本电脑到另一台笔记本电脑发送/接收数据,我使用的是
Python3.6
,看起来这个版本的python需要
.encode()
.decode()
函数,我使用的是
Python2.7
,以前我没有遇到任何问题,但是现在和
Python3.6
我必须使用这些函数,但是我不确定应该在哪里使用
.decode()
命令,您可以在我的服务器文件和客户机文件下面找到 服务器文件:

import socket
import threading
import os

def RetrFile(name, sock):
    filename = sock.recv(1024)
    filename.decode()
    if os.path.isfile(filename):
        sock.send("EXISTS " + str(os.path.getsize(filename)))
        userResponse = sock.recv(1024)
        if userResponse[:2] == 'OK':
            with open(filename, 'rb') as f:
                bytesToSend = f.read(1024)
                sock.send(bytesToSend)
                while bytesToSend != "":
                    bytesToSend = f.read(1024)
                    sock.send(bytesToSend)
    else:
        sock.send("ERR ")

    sock.close()

def MainServer():
    host = '172.16.1.2' #my IP adress
    port = 5000

    s = socket.socket()
    s.bind((host,port))

    s.listen(5)

    print ("Server Started.")
    while True:
        c, addr = s.accept()
        print ("client connected ip:<" + str(addr) + ">")
        t = threading.Thread(target=RetrFile, args=("RetrThread", c))
        t.start()

    s.close()

if __name__ == '__main__':
    MainServer()

谢谢你的帮助。

你发明了这个协议,所以你可以决定什么时候解码。一个选项是说基本协议(如OK和ERR始终是ascii,可以作为字节管理),但文件名和类似的内容是utf-8编码字符串,需要解码。但是二进制文件呢?您需要将流的该部分定义为二进制,或者对内容进行二进制到ascii编码

但它的方式比这更复杂。TCP是一种流协议。没有任何东西表明,
recv
获取另一方在一次调用中发送的所有内容,或者以方便的utf-8字符边界结束。您不能只
recv(1024)
而期望得到确切的消息边界

因此,是时候进行彻底的反思了:定义一个不同的协议。要遵循现有模式,可以使用基于ascii的标头,而不是以新行结尾。标头是一些命令或状态,后跟每个附加参数的字节大小,后跟换行符。之后将直接写入参数

您可以使用如下命令

STAT <sizeof utf-8 encoded file name>\n<utf-8-encoded-filename>
EXISTS ascii-encoded-size\n
DOWNLOAD <sizeof utf-8 encoded file name>\n<utf-8-encoded-filename>
标题告诉您管道中有多少数据,因此您可以为其配备一个读取器

def read_chunk(sock, size, encoding=None):
    buf = io.bytesIO()
    while size:
        tmp = sock.recv(min(size, 4096))
        if not tmp:
            raise OSError("Unexpected end of stream")
        buf.write(tmp)
        size -= len(tmp)
    if encoding:
        return buf.getvalue().encode(encoding)
    else:
        return buf.getvalue()
阅读这条小溪会很有趣

while True:
    hdr = read_header(sock)
    # try commands
    m = re.match(b"STAT (\d+)", hdr)
    if m:
        stat_size = int(m.group(1))
        file_name = read_chunk(sock, stat_size, 'utf-8')
        # do the stat work...
        continue
    m = re.match(b"DOWNLOAD (\d+)", hdr)
    etc...

通过传递
bytes
object
b“ERR”
而不是
str
object
“ERR”
,可以解决您眼前的问题。但是您知道如何对这行
sock.send(bytesToSend)
进行编码吗。感谢您无论何时需要将字符串转换为字节,都可以使用
str
类中的
encode()
方法,如
str.encode()
,或者更具体地说
str.encode(“utf-8”)
。所以在你的例子中,
bytesToSend.encode()
“ERR.encode()
。所以我猜应该是这样的:
bts=bytesToSend.encode()
sock.send(bts)!谢谢你的回答,我会尽量听你的。非常感谢。
def read_header(sock):
    hdr = []
    while True:
        c = sock.recv(1)
        if c == "\n":
            return ''.join(hdr).encode('ascii')
def read_chunk(sock, size, encoding=None):
    buf = io.bytesIO()
    while size:
        tmp = sock.recv(min(size, 4096))
        if not tmp:
            raise OSError("Unexpected end of stream")
        buf.write(tmp)
        size -= len(tmp)
    if encoding:
        return buf.getvalue().encode(encoding)
    else:
        return buf.getvalue()
while True:
    hdr = read_header(sock)
    # try commands
    m = re.match(b"STAT (\d+)", hdr)
    if m:
        stat_size = int(m.group(1))
        file_name = read_chunk(sock, stat_size, 'utf-8')
        # do the stat work...
        continue
    m = re.match(b"DOWNLOAD (\d+)", hdr)
    etc...