LINUX.ORG.RU

Передача стурктуры sendto, recfrom

 , ,


0

1

Естьучебный пример из книжки UDP сервера и клиента.
Захотелось мне попробовать отправить вместо строки
структуру.
Из клиента вроде как оптравляется, но на сервер не приходит.
tcpdump выдает несовпадение контрольной суммы.
14:10:38.713232 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 36)
localhost.42952 > localhost.8003: [bad udp cksum 7cf3!] UDP, length 8
14:10:38.713304 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 31)
localhost.8003 > localhost.42952: [bad udp cksum 5fed!] UDP, length 3
Но где я ошибка я понять не могу.
Разьясните, где ошибка?
Примеры прилагаются:

udpheader.h
#include <string.h>
#define INAME "From professionals to professionals"    
typedef struct {
unsigned int len;
char *isoname;
} Date;


udpServer.c
/* UDP Server */

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "udpheader.h"

#define MAXBUF 1024

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

    int udpSocket;
    int returnStatus = 0;
    int addrlen = 0;
    struct sockaddr_in udpServer, udpClient;
    char buf[MAXBUF];

    /* check for the right number of arguments */
    if (argc < 2)
    {
        fprintf(stderr, "Usage: %s <port>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* create a socket */
    udpSocket = socket(AF_INET, SOCK_DGRAM, 0);

    if (udpSocket == -1)
    {
        fprintf(stderr, "Could not create a socket!\n");
        exit(EXIT_FAILURE);
    } 
    else {
        printf("Socket created.\n");
    }

    /* setup the server address and port */
    /* use INADDR_ANY to bind to all local addresses */
    udpServer.sin_family = AF_INET;
    udpServer.sin_addr.s_addr = htonl(INADDR_ANY);

    /* use the port pased as argument */
    udpServer.sin_port = htons(atoi(argv[1]));

    /* bind to the socket */
    returnStatus = bind(udpSocket, (struct sockaddr*)&udpServer, sizeof(udpServer));

    if (returnStatus == 0) {
        fprintf(stderr, "Bind completed!\n");
    } 
    else {
        fprintf(stderr, "Could not bind to address!\n");
        close(udpSocket);
        exit(EXIT_FAILURE);
    }

	Date *d;
	d=NULL;
    
    while (1)
    {

        addrlen = sizeof(udpClient);

        returnStatus = recvfrom(udpSocket,&d, sizeof(*d), 0, (struct sockaddr*)&udpClient, &addrlen);

        if (returnStatus == -1) {

            fprintf(stderr, "Could not receive message!\n");
	    exit(EXIT_FAILURE);

        } 
        else {

			//	sprintf(OUT,"%s\n",d->isoname);

                //printf("Received: %s\n",d->isoname);

            /* a message was received so send a confirmation */
            strcpy(buf, "OK");

            returnStatus = sendto(udpSocket, buf, strlen(buf)+1, 0, 
                                  (struct sockaddr*)&udpClient, sizeof(udpClient));

            if (returnStatus == -1) {
                fprintf(stderr, "Could not send confirmation!\n");
            }
            else {
                printf("Confirmation sent.\n");

            }
        }

    }

    /*cleanup */
    close(udpSocket);
    return 0;
}

udpClient.c
/* UDP client */

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#define MAXBUF 1024
#include "udpheader.h"

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

    int udpSocket;
    int returnStatus;
    int addrlen;
    struct sockaddr_in udpClient, udpServer;
    char buf[MAXBUF];

    if (argc < 3)
    {
        fprintf(stderr, "Usage: %s <ip address> <port>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* create a socket */
    udpSocket = socket(AF_INET, SOCK_DGRAM, 0);

    if (udpSocket == -1)
    {
        fprintf(stderr, "Could not create a socket!\n");
        exit(EXIT_FAILURE);
    }
    else {
        printf("Socket created.\n");
    }

    /* client address */
    /* use INADDR_ANY to use all local addresses */
    udpClient.sin_family = AF_INET;
    udpClient.sin_addr.s_addr = INADDR_ANY;
    udpClient.sin_port = 0;

    returnStatus = bind(udpSocket, (struct sockaddr*)&udpClient, sizeof(udpClient));

    if (returnStatus == 0) {
        fprintf(stderr, "Bind completed!\n");
    }
    else {
        fprintf(stderr, "Could not bind to address!\n");
        close(udpSocket);
        exit(EXIT_FAILURE);
    }

    /* setup the message to be sent to the server */
    strcpy(buf, "For Professionals, By Professionals.\n");
   
    
    /* server address */ 
    /* use the command line arguments */
    udpServer.sin_family = AF_INET;
    udpServer.sin_addr.s_addr = inet_addr(argv[1]);
    udpServer.sin_port = htons(atoi(argv[2]));


    
    
	Date date,*d;
   	date.isoname=&INAME[0];
      	date.len=strlen(date.isoname);	
	d=&date;
	
   	printf("name: %s len: %d\n",d->isoname,d->len);
	returnStatus = sendto(udpSocket, (caddr_t) &d,sizeof(*d), 0, 
                          (struct sockaddr*)&udpServer, sizeof(udpServer));

    //returnStatus = sendto(udpSocket, buf,strlen(buf)+1, 0, 
    //                      (struct sockaddr*)&udpServer, sizeof(udpServer));
    if (returnStatus == -1) {
        fprintf(stderr, "Could not send message!\n");
    }
    else {

	
        printf("%s\n",d->isoname);

        /* message sent: look for confirmation */
        addrlen = sizeof(udpServer);
  
        returnStatus = recvfrom(udpSocket, buf, MAXBUF, 0, (struct sockaddr*)&udpServer, &addrlen);

        if (returnStatus == -1) {
            fprintf(stderr, "Did not receive confirmation!\n");
        }
        else {

            buf[returnStatus] = 0;
            printf("Received: %s\n", buf);
        }

    }

    /* cleanup */
    close(udpSocket);
    return 0;

}
★★

У тебя проблемы с указателями.

Date *d;
returnStatus = recvfrom(udpSocket,&d, sizeof(*d), 0, (struct sockaddr*)&udpClient, &addrlen);
returnStatus = sendto(udpSocket, (caddr_t) &d,sizeof(*d), 0, (struct sockaddr*)&udpServer, sizeof(udpServer));

Второй параметр - это адрес буфера, а не адрес адреса. d вообще не нужно.

unsigned ★★★ ()
Ответ на: комментарий от unsigned

И ещё подумай, стоит ли передавать указатели (date.isoname) между процессами.

unsigned ★★★ ()
Ответ на: комментарий от unsigned

d я сделал для усложнения эксперимента


returnStatus = sendto(udpSocket, &date,sizeof(date), 0,
                          (struct sockaddr*)&udpServer, sizeof(udpServer));

returnStatus = recvfrom(udpSocket,&date, sizeof(date), 0, 
(struct sockaddr*)&udpClient, &addrlen);

сделал таким образом, но ситуация не выправилась. пробовал записывать в буфер

char buf[1024];
memcpy(buf, &date, sizeof(date));
returnStatus = sendto(udpSocket, buf,strlen(buf)+1, 0,
                          (struct sockaddr*)&udpServer, sizeof(udpServer));
Но на сервере ничего по прежнему не принимается.

TomBOY ★★ ()
Ответ на: комментарий от unsigned

Есть намерение передать структуру целиком,
независимо от её наполнения, и после приёма на сервере устраивать её разбор.

TomBOY ★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.