IamRockAndRoll
01-06-2007, 19:04
Ciao a tutti! Ecco il problema che da un po' troppo ormai mi sta assillando: ho scritto un server che per prima cosa stabilisce una connessione TCP. Quando riceve il comando "PLAYcmd" fa partire un thread che ospita una "connessione" UDP. Quando però arriva alla funzione Recvfrom() viene restituito l'errore di Bad address. E proprio non riesco a capire perchè! Provando a isolare la parte di UDP, cioè eseguendo il codice cancellando la parte di TCP e quindi rimanendo con una sola "connessione" (UDP), funziona perfettamente!
Le funzioni con iniziale maiuscola sono wrappers con controllo di errore delle funzioni unix standard.
Qualsiasi aiuto è ben accetto.
Grazie
//SERVER
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include "errlib.h"
#include "sockwrap.h"
#define TCPPORT 3210
#define UDPPORT 3334
#define DIMBUF 4096
#define PARMcmd 11
#define PLAYcmd 12
#define STOPcmd 13
#define TERMcmd 14
void *UDPTransfer (void *ptr);
char * Capture (int * datalen);
void RecvParm (int TCPconn);
char * prog;
int main (int argc, char *argv[]) {
int listenfd, TCPconn;
struct sockaddr_in servaddr, cliaddr;
socklen_t cliaddrlen = sizeof(cliaddr);
pthread_t thread;
uint8_t buffer[8];
prog = argv[0];
listenfd = Socket (AF_INET, SOCK_STREAM, 0);
memset (&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(TCPPORT);
Bind (listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen (listenfd, 10);
while (1) {
TCPconn = Accept (listenfd, (SA *) &cliaddr, &cliaddrlen);
buffer[0] = -1;
while (buffer[0] != TERMcmd) {
Readn (TCPconn, buffer, 1);
switch (buffer[0]) {
case PARMcmd:
RecvParm (TCPconn);
break;
case PLAYcmd:
pthread_create (&thread, NULL, UDPTransfer, NULL);
break;
case STOPcmd:
pthread_cancel (thread);
break;
case TERMcmd:
pthread_cancel (thread);
Close (TCPconn);
return 0;
default:
puts ("Invalid command");
}
}
}
}
void *UDPTransfer (void *ptr) {
int UDPconn;
int len;
struct sockaddr_in addr;
char buffer[DIMBUF+1];
char * data;
int datalen;
UDPconn = Socket(AF_INET, SOCK_DGRAM, 0);
memset((void *)&addr, 0, sizeof(addr)); /* clear server address */
addr.sin_family = AF_INET; /* address type is INET */
addr.sin_port = htons(UDPPORT); /* daytime port is 13 */
addr.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */
Bind (UDPconn, (struct sockaddr *)&addr, sizeof(addr));
// Readn(UDPconn, buffer, DIMBUF);
Recvfrom(UDPconn, buffer, DIMBUF, 0, (struct sockaddr *)&addr, &len);
while (1) {
// esegue operazioni necessarie per la cattura e la manipolazione delle immagini
data = Capture (&datalen);
// Writen(UDPconn, data, datalen);
// invia l'immagine
Sendto(UDPconn, data, datalen, 0, (struct sockaddr *)&addr, sizeof(addr));
// termina se il client ha inviato il comando di stop
pthread_testcancel();
// esempio
Close(UDPconn);
return ptr;
}
}
// esempio
char * Capture (int * datalen) {
char string[30], * data;
strcpy (string, "Ciao, sono francesco!!!");
data = (char *)malloc (strlen(string) * sizeof (char));
strcpy (data, string);
*datalen = strlen (string);
return data;
}
void RecvParm (int TCPconn) {
return;
}
Qui c'è anche un client di esempio se dovesse servire
//CLIENT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include "errlib.h"
#include "sockwrap.h"
#define TCPPORT 3210
#define UDPPORT 3334
#define DIMBUF 4096
#define PARMcmd 11
#define PLAYcmd 12
#define STOPcmd 13
#define TERMcmd 14
void GoCapture (void);
void UDPtransfer (void);
char * address;
char * prog;
int main (int argc, char *argv[]) {
address = argv[1];
prog = argv[0];
GoCapture();
return 0;
}
void GoCapture (void) {
struct sockaddr_in servaddr;
int TCPconn;
uint8_t buffer[8];
TCPconn = Socket(AF_INET, SOCK_STREAM, 0);
memset (&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(TCPPORT);
inet_pton(AF_INET, address, &servaddr.sin_addr);
Connect (TCPconn, (SA*) &servaddr, sizeof(servaddr));
buffer[0] = PLAYcmd;
Writen (TCPconn, buffer, 1);
UDPtransfer();
}
void UDPtransfer (void) {
int UDPconn;
struct sockaddr_in addr;
char buffer[DIMBUF+1];
UDPconn = Socket(AF_INET, SOCK_DGRAM, 0);
memset((void *) &addr, 0, sizeof(addr)); /* clear server address */
addr.sin_family = AF_INET; /* address type is INET */
addr.sin_port = htons(UDPPORT); /* daytime port is 13 */
inet_pton(AF_INET, address, &addr.sin_addr);
Sendto(UDPconn, NULL, 0, 0, (struct sockaddr *)&addr, sizeof(addr));
Recvfrom(UDPconn, buffer, 23, 0, NULL, NULL);
buffer[23]='\0';
printf ("%s", buffer);
return;
}
Le funzioni con iniziale maiuscola sono wrappers con controllo di errore delle funzioni unix standard.
Qualsiasi aiuto è ben accetto.
Grazie
//SERVER
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include "errlib.h"
#include "sockwrap.h"
#define TCPPORT 3210
#define UDPPORT 3334
#define DIMBUF 4096
#define PARMcmd 11
#define PLAYcmd 12
#define STOPcmd 13
#define TERMcmd 14
void *UDPTransfer (void *ptr);
char * Capture (int * datalen);
void RecvParm (int TCPconn);
char * prog;
int main (int argc, char *argv[]) {
int listenfd, TCPconn;
struct sockaddr_in servaddr, cliaddr;
socklen_t cliaddrlen = sizeof(cliaddr);
pthread_t thread;
uint8_t buffer[8];
prog = argv[0];
listenfd = Socket (AF_INET, SOCK_STREAM, 0);
memset (&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(TCPPORT);
Bind (listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen (listenfd, 10);
while (1) {
TCPconn = Accept (listenfd, (SA *) &cliaddr, &cliaddrlen);
buffer[0] = -1;
while (buffer[0] != TERMcmd) {
Readn (TCPconn, buffer, 1);
switch (buffer[0]) {
case PARMcmd:
RecvParm (TCPconn);
break;
case PLAYcmd:
pthread_create (&thread, NULL, UDPTransfer, NULL);
break;
case STOPcmd:
pthread_cancel (thread);
break;
case TERMcmd:
pthread_cancel (thread);
Close (TCPconn);
return 0;
default:
puts ("Invalid command");
}
}
}
}
void *UDPTransfer (void *ptr) {
int UDPconn;
int len;
struct sockaddr_in addr;
char buffer[DIMBUF+1];
char * data;
int datalen;
UDPconn = Socket(AF_INET, SOCK_DGRAM, 0);
memset((void *)&addr, 0, sizeof(addr)); /* clear server address */
addr.sin_family = AF_INET; /* address type is INET */
addr.sin_port = htons(UDPPORT); /* daytime port is 13 */
addr.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */
Bind (UDPconn, (struct sockaddr *)&addr, sizeof(addr));
// Readn(UDPconn, buffer, DIMBUF);
Recvfrom(UDPconn, buffer, DIMBUF, 0, (struct sockaddr *)&addr, &len);
while (1) {
// esegue operazioni necessarie per la cattura e la manipolazione delle immagini
data = Capture (&datalen);
// Writen(UDPconn, data, datalen);
// invia l'immagine
Sendto(UDPconn, data, datalen, 0, (struct sockaddr *)&addr, sizeof(addr));
// termina se il client ha inviato il comando di stop
pthread_testcancel();
// esempio
Close(UDPconn);
return ptr;
}
}
// esempio
char * Capture (int * datalen) {
char string[30], * data;
strcpy (string, "Ciao, sono francesco!!!");
data = (char *)malloc (strlen(string) * sizeof (char));
strcpy (data, string);
*datalen = strlen (string);
return data;
}
void RecvParm (int TCPconn) {
return;
}
Qui c'è anche un client di esempio se dovesse servire
//CLIENT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include "errlib.h"
#include "sockwrap.h"
#define TCPPORT 3210
#define UDPPORT 3334
#define DIMBUF 4096
#define PARMcmd 11
#define PLAYcmd 12
#define STOPcmd 13
#define TERMcmd 14
void GoCapture (void);
void UDPtransfer (void);
char * address;
char * prog;
int main (int argc, char *argv[]) {
address = argv[1];
prog = argv[0];
GoCapture();
return 0;
}
void GoCapture (void) {
struct sockaddr_in servaddr;
int TCPconn;
uint8_t buffer[8];
TCPconn = Socket(AF_INET, SOCK_STREAM, 0);
memset (&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(TCPPORT);
inet_pton(AF_INET, address, &servaddr.sin_addr);
Connect (TCPconn, (SA*) &servaddr, sizeof(servaddr));
buffer[0] = PLAYcmd;
Writen (TCPconn, buffer, 1);
UDPtransfer();
}
void UDPtransfer (void) {
int UDPconn;
struct sockaddr_in addr;
char buffer[DIMBUF+1];
UDPconn = Socket(AF_INET, SOCK_DGRAM, 0);
memset((void *) &addr, 0, sizeof(addr)); /* clear server address */
addr.sin_family = AF_INET; /* address type is INET */
addr.sin_port = htons(UDPPORT); /* daytime port is 13 */
inet_pton(AF_INET, address, &addr.sin_addr);
Sendto(UDPconn, NULL, 0, 0, (struct sockaddr *)&addr, sizeof(addr));
Recvfrom(UDPconn, buffer, 23, 0, NULL, NULL);
buffer[23]='\0';
printf ("%s", buffer);
return;
}