Отправка данных при программировании сокетов с использованием «C» - PullRequest
4 голосов
/ 23 июля 2011

Ранее я публиковал вопрос, касающийся того же самого, но здесь я хочу руководство для своего кода. Используя советы от людей, которых я пытался создать для отправки пакета. Моя максимальная структура пакета вместе с заголовком и полезной нагрузкой составляет 16 байтов. Просьба, если возможно, просмотреть код отправки и получения и предложить, где я иду не так. По сути, мой клиент продолжает отправлять данные на сервер, он просто не заканчивается и сервер не показывает результаты.

Клиент:

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    struct packet
    { 
        long int srcID;
        long int destID;
        long int pver;
        long int profiles;
        char length;
        long int data;
    };
    if (argc < 3) {
        fprintf(stderr,"usage: %s hostname port\n", argv[0]);
        exit(0);
    }
    portno = atoi(argv[2]); //Convert ASCII to integer
    sockfd = socket(AF_INET, SOCK_STREAM, 0); // socket file descriptor

    if (sockfd < 0) 
        error("ERROR DETECTED !!! Problem in opening socket\n");

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

    bzero((char *) &serv_addr, sizeof(serv_addr)); //clear the memory for server address

    serv_addr.sin_family = AF_INET;    
    bcopy((char *)server->h_addr, 
    (char *)&serv_addr.sin_addr.s_addr,
    server->h_length);

    serv_addr.sin_port = htons(portno);

    printf("Client 1 trying to connect with server host %s on port %d\n", argv[1], portno); 

    if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) 
    error("ERROR in connection");

    printf("SUCCESS !!! Connection established \n");

    char buffer[128];
    struct packet *pkt = (struct packet *) buffer;
    char *payload = buffer + sizeof(struct packet);
    long int packet_size;

    printf("Started Creating packet\n");
    pkt->srcID = 0x01;
    pkt->destID = 0x02;
    pkt->pver = 0x01;
    pkt->profiles = 0x01;
    pkt->length = 128;
    pkt->data = 1; 2; 3; 4; 5; 6; 7; 8;


    if (send(sockfd,pkt,sizeof(packet_size),0) <0)
        printf ("error\n");
    else
        printf ("packet send done");
    return 0;
}

Сервер:

int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno, clilen;
    struct sockaddr_in serv_addr, cli_addr;
    int n;
    char wish;

    long int SrcID;
    long int DestID;
    long int Pver;
    long int Profiles;
    long int Data;
    char Length;
    char bytes_to_receive;
    char received_bytes;
    struct packet
    { 
        long int srcID;
        long int destID;
        long int pver;
        long int profiles;
        char length;
        long int data;
    };

    if (argc < 2) {
        fprintf(stderr,"usage: %s port_number1",argv[0]);
        exit(1);
    }
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR DETECTED !!! Problem in opening socket");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(portno);

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
        error("ERROR DETECTED !!! There was a problem in binding");

    listen(sockfd, 10);
    clilen = sizeof(cli_addr);

    printf("Server listening on port number %d...\n", serv_addr.sin_port); 

    newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);

    if (newsockfd < 0) 
        error("ERROR DETECTED !!! the connection request was not accepted");

    char buffer[128];
    struct packet *pkt = (struct packet *) buffer;
    char *payload = buffer + sizeof(struct packet);
    long int packet_size;

    bytes_to_receive = sizeof(pkt);
    received_bytes = 0;

    if (recv(newsockfd, pkt, sizeof(pkt), 0) < 0)
        error("ERROR DETECTED !!! There was a problem in reading the data");
    else
    { 
        do {
            received_bytes += (buffer + received_bytes, bytes_to_receive - received_bytes);
        } while (received_bytes != bytes_to_receive);

        SrcID = pkt->srcID;
        DestID = pkt->destID;
        Pver = pkt->pver ;
        Profiles = pkt->profiles;
        Length = pkt->length;
        Data = pkt->data;
        printf("Data Received from Client_1 are :\n");
        printf("Source ID: %l\n", SrcID);
        printf("Destination ID: %l\n", DestID);
        printf("profile Version: %l\n", Pver);
        printf("No of Profiles: %l\n", Profiles);
        printf("Length: %l\n", Length);
        printf("data : %l\n", Data);
    }
    if (close(newsockfd) == -1) {
        error("Error closing connection with client 1");
    }

    printf("Connection with client 1 has been closed\n");
    return 0; 
}

Сервер не показывает o / p. Клиент говорит, что отправил пакет. При компиляции серверного кода я вижу четыре предупреждения о неизвестных символах типа преобразования 0xa в формате для всех операторов printf в коде сервера. Я предполагаю, что я где-то не так на стороне кода сервера, но я не в состоянии следовать "сериализации". Пожалуйста, обновите меня своими данными, это очень поможет.

Ответы [ 3 ]

11 голосов
/ 23 июля 2011

Вот несколько проблем, которые я обнаружил:

  1. Ваш клиент продолжает отправлять пакеты, потому что он находится в бесконечном цикле while.
  2. Вы передали неверный параметр len функции recv.Прямо сейчас вы передаете sizeof (packet_size), который равен sizeof (long int) (4 байта в 32-битной ОС), но, вероятно, вы намеревались использовать sizeof (packet) (16 байтов).
  3. Вы не проверяете, сколько байтов было действительно прочитано функцией recv.С TCP у вас нет гарантии, что вы прочитали все 16 байтов пакета структуры.Поэтому время от времени вы можете читать меньше байтов, и ваш пакет будет неполным.Вот пример в некотором псевдокоде, как вы должны получить целый пакет:

    bytes_to_receive = sizeof(packet)
    received_bytes = 0;
    do {
        received_bytes += recv(buffer + received_bytes, bytes_to_receive - received_bytes)
    } while (received_bytes != bytes_to_receive)
    
  4. Ваша структура packet в клиенте и на сервере отличается.В одном вы используете char length;, во втором long int length;

  5. Я думаю, что такого рода назначения на сервере не имеют смысла pkt->srcID = SrcID; и должны быть примерно такими: SrcID = pkt->srcID;

3 голосов
/ 23 июля 2011

Проблема с клиентом, постоянно отправляющим, состоит в том, что вы просто делаете это в цикле. С исправленным отступом становится ясно, что произошло:

while (1)
{
    if (send(sockfd,pkt,sizeof(packet_size),0) <0)
        printf ("error\n");
    else
        printf ("packet send done");
}
0 голосов
/ 24 марта 2015
addr_size = sizeof serverAddr;

connect (clientSocket, (struct sockaddr *) и serverAddr, addr_size);

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