portnov
September 15th, 2006, 11:51 AM
Hello, i came across small problem while trying to send unknown size string over Sock-UDP type.
In normal sock-tcp you need to send string size first and then the string itself, right? - works like a charm, however, when it comes to UDP there is small problem - no one can assure you the size will be received before the data or one of them can be loosed in the way.
Here is my 2 functions i made for sendto/recivefrom :
int Socket::SendTo (char *buf, char *host) {
int nBytes_sent;
struct sockaddr_in server_addr; // connector's address information
struct hostent *he = gethostbyname(host);
server_addr.sin_family = AF_INET; // host byte order
server_addr.sin_port = htons(HPORT); // short, network byte order
server_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(server_addr.sin_zero), '\0', 8); // zero the rest of the struct
// get our message size
long bufferLen = (long) strlen (buf) + 1;
// fix our byte ordering
bufferLen = htonl (bufferLen);
// send the message size
if ((nBytes_sent = sendto(fd, (char *) &bufferLen, sizeof (bufferLen), 0,
(struct sockaddr *)&server_addr, sizeof(struct sockaddr)))
== SOCKET_ERROR){
printf ("Send size Failed!\n");
return -1;
}
// re-fix our byte ordering
bufferLen = ntohl (bufferLen);
// send the actual message
if ((nBytes_sent = sendto(fd, (char *) buf, bufferLen, 0,
(struct sockaddr *)&server_addr, sizeof(struct sockaddr)))
== SOCKET_ERROR){
printf ("Send message Failed!\n");
return -1;
}
return nBytes_sent;
}
int Socket::ReceiveFrom (char *buf){
// the number of bytes we received
int nBytes;
struct sockaddr_in clientAdr; // connector's address information
int clientAdrLen = sizeof (clientAdr);
// the size of the message that is being sent
unsigned long messageSize;
// receive the message size first
if((nBytes = recvfrom(fd, (char *) &messageSize, sizeof(messageSize), 0,
(struct sockaddr *)&clientAdr, (socklen_t*)&clientAdrLen)) == SOCKET_ERROR)
{
printf ("Recv Failed...\n");
return -1;
}
if (nBytes == 0)
{
printf ("Client on %d disconnected\n", fd);
return -1;
}
// convert the message size to host ordering
messageSize = ntohl (messageSize);
// receive the reset of the message
if((nBytes = recvfrom(fd, buf, messageSize, 0,(struct sockaddr *)&clientAdr, (socklen_t*)&clientAdrLen))== SOCKET_ERROR)
{
printf ("Recv data Failed! : %d\n",nBytes);
return -1;
}
buf[messageSize] = '\0';
printf("got packet from %s\n",inet_ntoa(clientAdr.sin_addr));
return nBytes;
}
Using function above - one on server and one on client will resolve in getting in most cases only the size.
Can anyone show me the solution to UDP unknown size data send?
Thanks in advance.
In normal sock-tcp you need to send string size first and then the string itself, right? - works like a charm, however, when it comes to UDP there is small problem - no one can assure you the size will be received before the data or one of them can be loosed in the way.
Here is my 2 functions i made for sendto/recivefrom :
int Socket::SendTo (char *buf, char *host) {
int nBytes_sent;
struct sockaddr_in server_addr; // connector's address information
struct hostent *he = gethostbyname(host);
server_addr.sin_family = AF_INET; // host byte order
server_addr.sin_port = htons(HPORT); // short, network byte order
server_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(&(server_addr.sin_zero), '\0', 8); // zero the rest of the struct
// get our message size
long bufferLen = (long) strlen (buf) + 1;
// fix our byte ordering
bufferLen = htonl (bufferLen);
// send the message size
if ((nBytes_sent = sendto(fd, (char *) &bufferLen, sizeof (bufferLen), 0,
(struct sockaddr *)&server_addr, sizeof(struct sockaddr)))
== SOCKET_ERROR){
printf ("Send size Failed!\n");
return -1;
}
// re-fix our byte ordering
bufferLen = ntohl (bufferLen);
// send the actual message
if ((nBytes_sent = sendto(fd, (char *) buf, bufferLen, 0,
(struct sockaddr *)&server_addr, sizeof(struct sockaddr)))
== SOCKET_ERROR){
printf ("Send message Failed!\n");
return -1;
}
return nBytes_sent;
}
int Socket::ReceiveFrom (char *buf){
// the number of bytes we received
int nBytes;
struct sockaddr_in clientAdr; // connector's address information
int clientAdrLen = sizeof (clientAdr);
// the size of the message that is being sent
unsigned long messageSize;
// receive the message size first
if((nBytes = recvfrom(fd, (char *) &messageSize, sizeof(messageSize), 0,
(struct sockaddr *)&clientAdr, (socklen_t*)&clientAdrLen)) == SOCKET_ERROR)
{
printf ("Recv Failed...\n");
return -1;
}
if (nBytes == 0)
{
printf ("Client on %d disconnected\n", fd);
return -1;
}
// convert the message size to host ordering
messageSize = ntohl (messageSize);
// receive the reset of the message
if((nBytes = recvfrom(fd, buf, messageSize, 0,(struct sockaddr *)&clientAdr, (socklen_t*)&clientAdrLen))== SOCKET_ERROR)
{
printf ("Recv data Failed! : %d\n",nBytes);
return -1;
}
buf[messageSize] = '\0';
printf("got packet from %s\n",inet_ntoa(clientAdr.sin_addr));
return nBytes;
}
Using function above - one on server and one on client will resolve in getting in most cases only the size.
Can anyone show me the solution to UDP unknown size data send?
Thanks in advance.