python - 从客户端 C、服务器 Python 问题发送套接字

标签 python c sockets

我当前的应用程序涉及一个 C 客户端使用 TCP 将文件发送到 Python 服务器。它将生成文件的哈希值并将信息发回。我可以让它与 python 客户端一起工作,但我在将客户端迁移到 C 时遇到问题。python 服务器仍未完成(它需要将文件大小字符串转换为 int、错误检查等)。

我现在最大的问题是服务器调用 hash_type = connbuff.get_utf8() 后,它给我哈希类型的第一个用户输入,然后关闭连接。我知道这是 get_utf8() 的问题,但我对如何解决这个问题感到困惑。我应该每次都从客户端发送任意数量的数据吗?请帮助我从我的方法错误中吸取教训!非常感谢任何意见/建议!谢谢=)

服务器.py

import socket
import os
import hashlib
import buffer

HOST = '127.0.0.1'
PORT = 2345

def getHash(fileName, hashType):
    ... hash algorithms ....

try:
    os.mkdir('uploads')
except FileExistsError:
    pass

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(10)
print("Waiting for a connection.....")

while True:
    conn, addr = s.accept()
    print("Got a connection from ", addr)
    connbuf = buffer.Buffer(conn)

while True:
    hash_type = connbuf.get_utf8()
        if not hash_type:
            break
        print('Hash Type: ', hash_type)

        file_name = connbuf.get_utf8()
        if not file_name:
            break
        print('File Name: ', file_name)
        file_name = os.path.join('uploads', file_name)

        file_size = connbuf.get_utf8()
        file_size = int(file_size)
        print('File Size: ', file_size)

        with open(file_name, 'wb') as f:
            remaining = file_size
            while remaining:
                if remaining >= 4096:
                    chunk_size = 4096
                else:
                    chunk_size = remaining
                chunk = connbuf.get_bytes(chunk_size)
                if not chunk:
                    break
                f.write(chunk)
                remaining -= len(chunk)

            if remaining:
                print('File incomplete: MISSING', remaining, 'BYTES.')
            else:
                print('File received successfully.')

        file_hash = getHash(file_name, hash_type)
        response = file_name + ' ' + file_hash
        connbuf.put_utf8(response)

print('Connection closed.')
conn.close()

我的 Buffer 类 get_utf8() 和 get_bytes() 看起来像这样...

def __init__(self,s):
    self.sock = s
    self.buffer = b''

def get_bytes(self,n):
    while len(self.buffer) < n:
        data = self.sock.recv(1024)
        if not data:
            data = self.buffer
            self.buffer = b''
            return data
        self.buffer += data

    data,self.buffer = self.buffer[:n],self.buffer[n:]
    return data

def get_utf8(self):
    while b'\x00' not in self.buffer:
        data = self.sock.recv(1024)
        if not data:
            return ''
        self.buffer += data

    data,_,self.buffer = self.buffer.partition(b'\x00')
    return data.decode()

客户端.c

#include <sys/socket.h>
  ... more includes ...

#define PORT_NUMBER 2345
#define SERVER_ADDRESS "127.0.0.1"

char *inputString(FILE* fp, size_t size){
    ... string input code ...
}

int main () {
    int server_socket, connection_status;
    struct sockaddr_in serverAddress;
    char *hashType;
    char *fileName;
    char send_buffer[4000];
    FILE * file_to_send;
    int file_size;

/* Connect to Server */
    ... connect to server code ...

/* Get Hash an File User Input */
printf("Enter hash type: ");
hashType = inputString(stdin, 10);
printf("Hash type: %s\n", hashType);

printf("Enter file name: ");
fileName = inputString(stdin, 10);
printf("File Name: %s\n");

/* Send User Input */
send(server_socket, hashType, sizeof(hashType), 0);
send(server_socket, fileName, sizeof(fileName), 0);

/* Open File, Get Size, Convert to String */
file_to_send = fopen(fileName, "rb");
fseek(file_to_send, 0, SEEK_END);
file_size = ftell(file_to_send);
fseek(file_to_send, 0, SEEK_SET);

int l = snprintf(NULL, 0, "%d", file_size);
char *str_file_size;
asprintf(&str_file_size, "%i", file_size);
printf("%s\n", str_file_size);

/* Send File Size and File */
send(server_socket, str_file_size, sizeof(str_file_size), 0);

while(!feof(file_to_send)) {
    fread(send_buffer, 1, sizeof(send_buffer) - 1, file_to_send);
}
send(server_socket, send_buffer, sizeof(send_buffer), 0);

return 0;

}

最佳答案

get_utf8 期望从套接字读取一个以 null 结尾的 UTF-8 编码字符串。在 C 代码中,您发送 sizeof(hashType)hashType 是一个指针,因此您发送的正好是 4 或 8 个字节(取决于 32 位或 64 位架构)。您可能需要 strlen(hashType)+1 (+1 表示 NULL)。文件名同上。

get_utf8 也会读取,直到看到 null。如果它从未看到,它会返回空字符串,这会导致接收代码中断并关闭连接。

关于python - 从客户端 C、服务器 Python 问题发送套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53231788/

相关文章:

c# - 在两个不同端口上连接到服务器的 TCP 套接字

python - pip 无法确认 SSL 证书 : SSL module is not available

python - 在Python中使用相同的整数对不同列中的相同值进行编码

c - C中的多个警报?

java/android TCP sockets - 检测服务器是否离线

c# - 聊天服务应用

python - Django rest 框架使用 user.id 自动填充字段

python - 使用 Django 编写文件上传 API

c - 向程序中添加升序计时器

c - 如何从源文件中提取单个函数