Программирование сокетов - сообщение получено не правильно - PullRequest
0 голосов
/ 27 октября 2019

Я новичок в программировании сокетов. Я пытаюсь создать серверную / клиентскую программу для загрузки файла.

Во-первых, я запускаю какой-то шаг, который я обычно делаю в другой программе, для настройки подключения клиента к серверу из формы.

Далее, со стороны сервера, я пытаюсь ввести количество байтов, которые отправляются клиенту, чтобы установить размер буфера приема. Со стороны клиента я получаю число в виде строки. Я конвертирую его в тип long и устанавливаю размер буфера.

Затем со стороны клиента я ввожу имя файла, который нужно загрузить с сервера. Сервер получает имя и проверяет, существует оно или нет.

Последний шаг (я думаю, ПРОБЛЕМА ШАГА) сервер пытается открыть файл. если файл открыт, отправьте имя файла обратно клиенту. клиент проверяет имя файла, если оно совпадает с отправленным или нет.

======> моя проблема в том, что имя файла отправляется обратно клиенту: - со стороны сервера: я распечатываю его и проверяю. это верно. - С клиента: я печатаю буфер сразу после чтения с сервера. Это не правильно. иногда пустоиногда это случайное значение.

Я сделал точно так же, как и предыдущий шаг.

Server.cpp

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

using namespace std;

int main(int argc, char *argv[])

{
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    struct sockaddr_in serv_addr, cli_addr;
    int n;

    if (argc < 2) 
    {
        perror("you have to input port");
        exit(1);
    }


    // init sockfd
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("sockfd perror");
        exit(1);
    }

    // sockopt
    int opt = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) 
    { 
        perror("setsockopt"); 
        exit(EXIT_FAILURE); 
    }

    // init server
    bzero(&serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    // bind port
    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    {
        perror("ERROR on binding");
        exit(1);
    } 

    listen(sockfd, 5);
    clilen = sizeof(cli_addr);
    newsockfd = accept(sockfd, 
                (struct sockaddr *) &cli_addr, 
                &clilen);
    if (newsockfd < 0) 
    {
        perror("ERROR on accept");
        exit(1);
    }

    char buffer[256];
    // write buff size
    int buffsize;
    printf("Input recive buffsize in Byte: ");
    scanf("%d", &buffsize);
    if (buffsize <= 0)
    {
        perror("Buffer size must be > 0");
        exit(1);
    }

    bzero(buffer, sizeof(buffer));
    bcopy(to_string(buffsize).c_str(), buffer, sizeof(buffer));
    n = write(newsockfd, buffer, sizeof(buffer));
    if (n < 0)
    {
        perror("fail to send buffer size");
        exit(0);
    }

    //read file name
    bzero(buffer, sizeof(buffer));
    n = read(newsockfd, buffer, sizeof(buffer));
    if (n < 0) 
    {
        perror("ERROR reading from socket");
        exit(1);
    }

    // open file:
    char filename[strlen(buffer) + 1];
    bcopy(buffer, filename, sizeof(filename));

    FILE *pf;
    unsigned long fsize;
    pf = fopen(filename, "rb");
    if (pf == NULL) 
    {
        bzero(buffer, sizeof(buffer));
        bcopy("File not found", buffer, sizeof(buffer));
        n = write(newsockfd, buffer, sizeof(buffer));
        if (n < 0)
        {
            perror("ERROR writing to socket");
            exit(1);
        }

        printf("File not found!\n");
        return 1;
    }
    else 
    {
        printf("File %s is openned \n", filename);

        fseek(pf, 0, SEEK_END);
        fsize = ftell(pf);
        rewind(pf);

        printf("File has %ld bytes!\n", fsize);
    }

    // write OK response file name
    bzero(buffer, sizeof(buffer));
    bcopy(filename, buffer, sizeof(buffer));
    printf("\n\n\n\n%s\n\n\n\n", buffer);
    n = write(newsockfd, buffer, sizeof(buffer));
    if (n < 0) 
    {
        perror("ERROR writing to socket");
        exit(1);
    }


    close(newsockfd);
    close(sockfd);

    return 0; 
}

Client.cpp

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

using namespace std;

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    if (argc < 3) 
    {
       fprintf(stderr, "usage %s hostname port\n", argv[0]);
       exit(0);
    }
    portno = atoi(argv[2]);

    // init sockfd
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
    {
        perror("sockfd error");
        exit(1);
    }

    // init server
    server = gethostbyname(argv[1]);
    if (server == NULL) 
    {
        fprintf(stderr, "ERROR, no such host\n");
        exit(0);
    }

    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
    serv_addr.sin_port = htons(portno);

    // connect
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
    {
        perror("ERROR connecting");
        exit(1);
    }

    // recive and set buffer size:
    char tempBuff[10];
    bzero(tempBuff, 10);
    n =  read(sockfd, tempBuff, sizeof(tempBuff));
    if (n < 0)
    {
        perror("fail to recive buffer size");
        exit(1);
    }

    char buffer[stol(string(tempBuff))];


    printf("Connect succes, Buffer size is %ld Bytes\n", sizeof(buffer));

    // input file:
    printf("Input file name to download: ");
    string filename;
    cin >> filename;

    // Send filename 
    bzero(buffer, sizeof(buffer));
    bcopy(filename.c_str(), buffer, filename.length());
    n = write(sockfd, buffer, strlen(buffer));
    if (n < 0) 
    {
        perror("ERROR writing to socket");
    }

    // read file name response
    bzero(buffer, sizeof(buffer));
    n = read(sockfd, buffer, sizeof(buffer));
    if (n < 0)
    {
        perror("ERROR reading from socket");
    }
    printf("\n\n\n\n%s, %ld\n\n\n\n", buffer, strlen(buffer));
    // if (strcmp(buffer, filename.c_str()) == 0)
    // {
    //     printf("OK!\n");
    // }
    // else
    // {
    //     perror("Wrong filename");
    //     printf("server msg: %s\n", buffer);
    //     exit(1);
    // }

    close(sockfd);
    return 0;
}

КОД ВЫПОЛНЕНИЯ С СЛЕДУЮЩЕЙ КОМАНДОЙ:

Клиент: ./client [ip сервера] [порт]

Сервер: ./server [порт]

Мой результат:

enter image description here


Обновление 1: проблема исчезает, когда я удаляю следующие строки:

// write buff size
    int buffsize;
    printf("Input recive buffsize in Byte: ");
    scanf("%d", &buffsize);
    if (buffsize <= 0)
    {
        perror("Buffer size must be > 0");
        exit(1);
    }

в server.cpp и этистрока:

// recive and set buffer size:
    bzero(tempBuff, sizeof(tempBuff));
    n =  read(sockfd, tempBuff, sizeof(tempBuff));
    if (n < 0)
    {
       perror("fail to recive buffer size");
        exit(1);
    }

    // char buffer[stol(string(tempBuff))];

на client.cpp

1 Ответ

0 голосов
/ 27 октября 2019

Я решил это. эта проблема возникает из-за слишком малого tempBuff. это всего лишь 10 байтов. Использование большего tempBuff решит проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...