【问题标题】:Python Socket Server receives gibberish text files, after client sends an text file在客户端发送文本文件后,Python Socket Server 接收到乱码文本文件
【发布时间】:2021-06-07 14:08:51
【问题描述】:

我创建了一个客户端(C 语言来发送文件)和服务器(Python 语言来接收)来测试发送和接收 .txt 文件。 但是,当我尝试使用服务器发送和接收它时,接收到的文件包含原始文本+乱码文本。 下面是 Python 中的服务器代码(接收文件):

import socket

#Set up socket
IP_SERVER = "127.0.0.1"
HEADER = 1024
PORT = 15000
ADDR = (IP_SERVER,PORT)
FORMAT = "utf-8"

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(ADDR)
server_socket.listen()


#Set up file 
file =open("dari_client.txt","wb")
connected = True
while connected :
    conn,addr = server_socket.accept()
    terima = conn.recv(HEADER).decode(FORMAT)
    print("Client connected \n")
    while terima:
        file.write(terima)
        terima = conn.recv(HEADER).decode(FORMAT)
    file.close()
    connected = False

conn.close()

以下是我的 C 语言客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <unistd.h> 
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h> 
#include <netinet/in.h>

void kirim_file(int socket,FILE *fl)
{
    int n;
    char data[1024];
    while (fgets(data,1024,fl) != NULL){
        send(socket,data,sizeof(data),0);
    }
    bzero(data,1024);
}

int main(){
    int network_socket,cli;
    FILE *fl;
    char nama_file[20] = "pesan.txt";
    network_socket = socket(AF_INET ,SOCK_STREAM, 0);

    // socket server address
    struct sockaddr_in server_address,client_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(15000);
    server_address.sin_addr.s_addr = inet_addr("127.0.0.1");

    connect(network_socket, (struct sockaddr *) &server_address, sizeof(server_address));
    fl = fopen(nama_file,"r");
    kirim_file(network_socket,fl);

    close(network_socket);
}
 

在这张图片中可以看到胡言乱语: Gibberish received file

知道如何解决这个问题吗?

【问题讨论】:

  • 尝试不拨打.decode(FORMAT)。顺便说一句,您使用的是什么 python 版本,它允许您将字符串(而不是 .recv 返回的字节对象)写入以 mode='wb' 打开的文件?
  • 原始文本文件是什么格式?我怀疑它是 ascii,并且由于解码不尊重多字节文本的网络字节顺序,所以它完全错了。
  • 对不起,我刚刚看到 c 代码包含一个错误:send(socket,data,sizeof(data),0); 总是发送 1024 个字节,但您只想一次发送一行。你想要strlen(data) 而不是sizeof
  • @JustinEzequiel 已经尝试不使用 .decode(format) 并且我得到一个“utf8”编解码器无法解码字节......”错误
  • 嗨@pqans,当我保存文本文件时,它是UTF-8,将尝试使用strlen(数据),谢谢

标签: python c sockets tcp utf-8


【解决方案1】:

这很可能至少部分是因为您发送的是整个数组data,而不仅仅是您从文件中读取的内容。来自string.h 的手册页:

char *fgets(char *s, int size, FILE *stream)

fgets() 从流中最多读入一个小于 size 的字符并将它们存储到 s 指向的缓冲区中。 在 EOF 或换行符后停止读取。如果读取了换行符,则将其存储到缓冲区中。终止空字节 ('\0') 存储在缓冲区中的最后一个字符之后。

因此,每次您读取文件时,您都会发送读取的数据以及存储在缓冲区data 其余部分中的所有垃圾数据。可能最简单的方法是检查读取的数据量,而不是每次都发送所有data

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <unistd.h> 
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h> 
#include <netinet/in.h>

void kirim_file(int socket,FILE *fl)
{
    int n;
    char data[1024];

    while (fgets(data, 1024, fl) != NULL){
        int length = strnlen(data, 1024);

        send(socket, data, length, 0);
    }

    bzero(data,1024);
}

【讨论】:

  • 嗨,我会尝试这样做,我会更新你的结果,谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-10-15
  • 2018-11-19
  • 2012-04-28
  • 2023-04-03
  • 2016-03-10
  • 1970-01-01
  • 2018-10-27
  • 1970-01-01
相关资源
最近更新 更多