Сервер UDP не получает в Unix (Cygwin) - PullRequest
0 голосов
/ 06 ноября 2011

Итак, я осмотрелся и заметил, что у некоторых других была похожая проблема с моей. Однако мне еще предстоит найти решение. Я создал клиент и сервер в Unix (Cygwin), используя UDP. Когда я пытаюсь использовать sendto () для отправки сообщения на сервер от клиента, сервер, кажется, не получает пакет. Я сделал проверку ошибок, и похоже, что у клиента нет проблем с отправкой пакета, но сервер все равно не может получить его правильно. Сервер просто кажется мертвым по большей части. Я использую свой компьютер для размещения клиента и сервера и пытаюсь подключиться к серверу по своему домашнему адресу (127.0.0.1) и случайному порту. Любые предложения на данный момент будет принята с благодарностью.

Код сервера:

#include <stdio.h>  /* standard C i/o facilities */
#include <stdlib.h> /* needed for atoi() / atof() */
#include <unistd.h> /* Unix System Calls */
#include <sys/types.h>  /* system data type definitions */
#include <sys/socket.h> /* socket specific definitions */
#include <netinet/in.h> /* INET constants and stuff */
#include <arpa/inet.h>  /* IP address conversion stuff */
#include <string.h> /* String manipulation */
#include <time.h> /* Used to to measure process execution time */


/* Server main routine - this is an iterative server

1. create a socket
2. bind the socket and print out the port number assigned
3. do forever
    get next connection
    handle the connection 
  enddo
*/


int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
int n;

//Create UDP socket
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
    perror("Problem creating socket\n");
    exit(1);
}

//Setup the UDP server
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(0);

//Bind the UDP to the socket
if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
{
    perror("Error bind\n");
    exit(1);
}

//Print the port for the UDP server
int length = sizeof( servaddr );
if (getsockname(sockfd, (struct sockaddr *) &servaddr, &length) < 0)
{
    perror("Error getsockname\n");
    exit(1);
}
printf("The Server passive socket port number is %d\n",ntohs(servaddr.sin_port));

//Send/Recv from client
char msg[100];
for(;;)
{
    socklen_t len = sizeof(cliaddr);
    if( recvfrom(sockfd, msg, 100, 0, (struct sockaddr*) &cliaddr, &len) < 0)
    {
        perror("Error on recv\n");
        exit(1);
    }
    printf("Msg: %s\n", msg);
    //read(sockfd, msg, 10);
    //sendto(sockfd, msg, n, 0, (struct sockaddr*) &cliaddr, len);
}

close(sockfd);
return 0;
}

Код клиента:

#include <stdio.h>  /* standard C i/o facilities */
#include <stdlib.h> /* needed for atoi() */
#include <unistd.h> /* Unix System Calls */
#include <sys/types.h>  /* system data type definitions */
#include <sys/socket.h> /* socket specific definitions */
#include <netinet/in.h> /* INET constants and stuff */
#include <arpa/inet.h>  /* IP address conversion stuff */
#include <string.h>


/* client program:

 The following must passed in on the command line:

  name of the server (argv[1])
  port number of the server (argv[2])
*/

int main( int argc, char **argv )
{
int sockfd;
struct sockaddr_in servaddr;
int n;

//Ensure we have full args
if (argc != 3)
{
    printf("Usage: client <server name> <server port>\n");
    exit(1);
}

//Setup the port number
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));

//Setup the client IP
//inet_pton(AF_INET, argv[1], &servaddr.sin_addr)) <= 0
if( inet_aton(argv[1], &servaddr.sin_addr) == 0)
{
    perror("Error with server IP\n");
    exit(1);
}

//Create socket
if( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
    perror("Error on socket\n");
    exit(1);
}

/*if (connect(sockfd,(struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 )
{
    printf("Problem connecting socket\n");
    exit(1);
}*/

//Send msg

char msg[10] = "123456789";
for(;;)
{
    socklen_t len = sizeof(servaddr);
    if( (sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr*) &servaddr, len)) < 0 )
    {
        perror("Error on sendto():\n");
        exit(1);
    }
    //write(sockfd, msg, strlen(msg));
    //n = recvfrom(sockfd, msg2, 10, 0, NULL, NULL);
    //printf("Msg: %s\n", msg2);
}

close(sockfd);
return 0;
}

1 Ответ

0 голосов
/ 06 ноября 2011

Во-первых, ваш отправитель просто отправляет данные настолько быстро, насколько это возможно, независимо от того, слушает ли кто-то или что-то еще.Это не очень хорошая вещь.

Во-вторых, ваш приемник передает msg в спецификатор %s printf.Но %s только для строк в стиле C, а msg - это , а не в стиле C (ничто не помещает нулевой байт в конец).Вы также выбрасываете возвращаемое значение recvfrom, поэтому не можете преобразовать его в строку, потому что не знаете, сколько его байтов допустимо.

В-третьих, ваш сервер создает сокет SOCK_STREAM.!

...