c - 奇怪的文件输出套接字文件传输

标签 c

所以,我正在制作一个套接字程序来连接两个程序,到目前为止一切正常;设置winsock、连接和交互。然而,从客户端发送到服务器端的文件中有奇怪的字符。

示例:

File: test.txt
Contents: Hey, how are you?
** Client sends file over to Server **
Expected Output: Hey, how are you?
Actual Output:  7_ Ä _

服务器代码:

int main() {
    WSADATA Winsock;
    SOCKET Socket, Sub;
    Addr addr;
    IncomingAddress incomingAddress;
    int AddressLen = sizeof(IncomingAddress);

    // Start up Winsock
    WSAStartup(MAKEWORD(2, 2), &Winsock);

    if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) {
        WSACleanup();
        return 0;
    }

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    // Memset alternative
    ZeroMemory(&addr, sizeof(Addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(portNumber);
    bind(Socket, (sockaddr*) &addr, sizeof(Addr));

    if (listen(Socket, 1) == SOCKET_ERROR) {
        printf("Listening error!\n");
    } else {
        printf("Listening...\n");
    }

    if (Sub = accept(Socket, (sockaddr*) &incomingAddress, &AddressLen)) {
        int Size;
    char *Filesize = malloc(MAX_PATH);

    if (recv(Socket, Filesize, MAX_PATH, 0)) { // File Size
        Size = atoi((const char*) Filesize);
        printf("File size: %d\n", Size);
    }

    char *Buffer = malloc(Size);

    int Offset = 0;
    while (Size > Offset) {
        printf("TESST");
        int Amount = recv(Socket, Buffer + Offset, Size - Offset, 0);

        if (Amount <= 0) {
            printf("Error: " + WSAGetLastError());
            break;
        } else {
            Offset += Amount;
        }
    }

    FILE *File;
    File = fopen("test.txt", "wb+");
    fwrite(Buffer, 1, Size, File);
    fclose(File);

    getchar();
    closesocket(Socket);
    WSACleanup();

    }
 }
 return 0;
}

客户端代码:

int main() {
    WSADATA Winsock;
    SOCKET Socket, Sub;
    Addr addr;
    IncomingAddress incomingAddress;
    int AddressLen = sizeof(IncomingAddress);

    WSAStartup(MAKEWORD(2, 2), &Winsock);

    if (LOBYTE(Winsock.wVersion) != 2 || HIBYTE(Winsock.wVersion) != 2) {
        WSACleanup();
        return 0;
    }

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    ZeroMemory(&addr, sizeof(Addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(6000);

    if (connect(Socket, (sockaddr*) &addr, sizeof(Addr)) < 0) {
        printf("Connection Failed!\n");
        getchar();
        return 0;
    }

        char *ClientIP = inet_ntoa(incomingAddress.sin_addr);
        int ClientPort = ntohs(incomingAddress.sin_port);
        printf("Client connected!\n");
        printf("IP: %s:%d\n", ClientIP, ClientPort);

        printf("Sending file... \n");

        FILE *File;
        char *Buffer;
        unsigned long Size;

        File = fopen("test.txt", "rb+");
        if (!File) {
            printf("Error while reading the file!\n");
            getchar();
            return 0;
        }

        fseek(File, 0, SEEK_END);
        Size = ftell(File);
        fseek(File, 0, SEEK_SET);

        Buffer = malloc(Size);

        fread(Buffer, Size, 1, File);
        char cSize[MAX_PATH];
        sprintf(cSize, "%i", Size);

        fclose(File);
        send(socket, cSize, MAX_PATH, 0); // File size

        int Offset = 0;
        while (Size > Offset) {
            int Amount = send(Sub, Buffer + Offset, Size - Offset, 0);

            if (Amount <= 0) {
                printf("Error: " + WSAGetLastError());
                break;
            } else {
                Offset += Amount;
            }
        }
        free(Buffer);
        closesocket(Sub);
        closesocket(Socket);
        WSACleanup();
        printf("File sent!\n");
    return 0;
}

最佳答案

您遇到三个问题,一个在客户端,两个在服务器。

在客户端中,您通过Socket发送文件的大小,这是正确的。但随后您使用未连接且未初始化的套接字 Sub 来发送文件的数据。

在服务器中,您遇到几乎相反的问题,您尝试通过被动监听 socket 而不是接受的连接套接字 Sub 接收大小和数据.

同样在服务器中,如果读取数据时出现错误,您会报告错误,但无论如何都会将数据写入文件。在这种情况下,它将是一些未知长度的未初始化数据。

使用正确的套接字,如果出现错误,不要做不应该做的事情。

实际上做了一些错误检查。当在服务器中接收大小时,您不会检查错误,只是检查连接是否被连接的另一端关闭。

关于c - 奇怪的文件输出套接字文件传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40173339/

相关文章:

c - 并内并和 splinter 矩阵加法

c - 是否可以使用ECC私钥进行加密?

c# - vs2012 c# 与unix c server socket通信

c - 在阻塞 recv 调用的情况下,如果对等方系统重新启动,则调用不会来自 out recv。为什么?

C fscanf 添加一个元素到数组,不应该

c - 信号量意外设置

c++ - 放大率低于 125% 默认 Win API(101 - 124% 之间)

c - 结构体/结构体值的内存分配

c - 未定义对 'function square' 的引用

在C中使用sqlite3调用两个使用不同数据库的函数