Я столкнулся с проблемой с UDP-сокетами.
Для этой конкретной программы один файл .c должен быть и клиентом для другого сервера (через TCP), и сервером / клиентом для себя (выполняется дважды, работает на отдельных серверах). Он будет работать дважды одновременно, и поскольку он должен иметь возможность одновременно выполнять подключение TCP (для одного типа данных) и соединение UDP (для другого типа данных), это необходимо сделать с нитями или вилками, но я использовал темы.
У меня проблема в том, что UDP-сокеты не получают дейтаграмм друг от друга. Нет ошибок компиляции, и он работает нормально, но нет выходных данных, кроме общих отладочных операторов печати. Он застревает в командах recvfrom.
Код ниже разделен на две части (опять же, в одном и том же файле .c). Верхняя часть - это раздел сервера, а нижняя часть - это раздел клиента. Это все сделано в потоке. Я попытался создать сокет ТО, вызывая поток с клиентским кодом (идея заключалась в том, что поток связывался бы с родителем, но это не имело значения), но он получал тот же результат. Итак, на данный момент поток обрабатывает только UDP-соединение, а родительский обрабатывает TCP.
Если вам нужно больше объяснений, пожалуйста, не стесняйтесь спрашивать. Это для школьного задания, поэтому я не могу дать СЛИШКОМ много, но я скажу, что могу.
Спасибо!
БЫСТРОЕ РЕДАКТИРОВАНИЕ: весь этот код, приведенный ниже, просто отправляет привет на сервер и обратно клиенту. Дальнейшие детали не нужны.
Предположим, что argv->stuff
- это структура, которую я передал потоку, и что пользователь предоставляет сервер, IP-адрес и порт при выполнении.
//----- Server portion of code is below
int cli2_sockfd;
char buffer_cli2[MAXLINE];
char *hello2 = "Hello from client 2";
struct sockaddr_in cli2_addr, client1_addr;
int clis_portno = atoi(argv->port);
clis_portno = clis_portno + 1;
// Creating socket file descriptor
if ( (cli2_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&cli2_addr, 0, sizeof(cli2_addr));
memset(&client1_addr, 0, sizeof(client1_addr));
// Filling server information
cli2_addr.sin_family = AF_INET; // IPv4
cli2_addr.sin_addr.s_addr = INADDR_ANY;
cli2_addr.sin_port = htons(clis_portno);
// Bind the socket with the server address
if ( bind(cli2_sockfd, (const struct sockaddr *)&cli2_addr,
sizeof(cli2_addr)) < 0 )
{
perror("bind failed");
exit(EXIT_FAILURE);
}
while(1)
{
int n2;
socklen_t len2;
if((n2 = recvfrom(cli2_sockfd, (char *)buffer_cli2, MAXLINE,
0, ( struct sockaddr *) &client1_addr,
&len2)) < 0)
{
perror("svr recvfrom");
exit(EXIT_FAILURE);
}
buffer_cli2[n2] = '\0';
printf("Client 1: %s\n", buffer_cli2);
if(sendto(cli2_sockfd, (const char *)hello2, strlen(hello2),
MSG_CONFIRM, (const struct sockaddr *) &client1_addr,
len2) < 0)
{
perror("svr sendto");
exit(EXIT_FAILURE);
}
printf("Hello message sent.\n");
}
//----- The client portion of the code is below
int client1_sockfd;
char buffer[MAXLINE];
char *hello1 = "Hello from client 1";
struct sockaddr_in client2_addr;
struct hostent *client_2;
clis_portno = atoi(argv->port);
clis_portno = clis_portno + 1;
// Creating socket file descriptor
if ( (client1_sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&client2_addr, 0, sizeof(client2_addr));
if((client_2 = gethostbyname(argv->name)) == NULL)
{
perror("cli gethostbyname");
exit(EXIT_FAILURE);
}
bzero((char *) &client2_addr, sizeof(client2_addr));
// Filling Client 2 information
client2_addr.sin_family = AF_INET;
bcopy((char *)client_2->h_addr, (char *)&client2_addr.sin_addr.s_addr, client_2->h_length);
client2_addr.sin_port = htons(clis_portno);
while(1)
{
int n1;
socklen_t len1;
if( sendto(client1_sockfd, (const char *)hello1, strlen(hello1),
0, (const struct sockaddr *) &client2_addr,
sizeof(client2_addr)) < 0)
{
perror("cli sendto");
exit(EXIT_FAILURE);
}
printf("IN THREAD: Hello1 = %s\n", hello1);
if((n1 = recvfrom(client1_sockfd, (char *)buffer, MAXLINE,
MSG_WAITALL, (struct sockaddr *) &client2_addr,
&len1)) < 0)
{
perror("cli recvfrom");
exit(EXIT_FAILURE);
}
buffer[n1] = '\0';
printf("IN THREAD: Client 2 : %s\n", buffer);
}