LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-22-2010, 02:36 PM   #1
fneves
LQ Newbie
 
Registered: Nov 2010
Posts: 8

Rep: Reputation: 4
Socket - problem at recvfrom function


#
Hi.
I'm doing a program where basically I want inside the while loop information is sent only at certain moments and is always listening to new information. My problem is that the function to read the buffer is blocking me the while. I've tried some solutions here in the forum as:

int flags = fcntl(sock, F_GETFL);
flags |= O_NONBLOCK;
fcntl(sock, F_SETFL, flags);

However, I am not succeeding. This is my code. What should I change it (and how)?

/*
** talker.c -- a datagram "client" demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define SERVERPORT 4950 // the port users will be connecting to


#define MAXBUFLEN 100

#include <time.h>
#include <iostream>
#include <list>
#include <fstream>



#include <fcntl.h>




typedef struct
{
int id;
int send_time; //send time
int ACK;
int recv_time; //receive time
} myPacket;

int main(int argc, char *argv[])
{
using namespace std;

int sockfd;
struct sockaddr_in their_addr; // connector's address information
struct hostent *he;
int numbytes;
int ID=1;

time_t init;
socklen_t addr_len;

myPacket packet;
unsigned char buffer[sizeof(packet)];

time_t epoch_time;
epoch_time = time( NULL ); //time in seconds (since 1 Jan 1970)
init=epoch_time+5;

list<myPacket> packets; //list of packets
list<myPacket>::iterator it;

ofstream success;
ofstream dropped;
success.open ("Success.txt");
dropped.open ("Dropped.txt");



int flags = fcntl(sockfd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flags);




if ((he=gethostbyname(argv[1])) == NULL) // get the host info
{
herror("gethostbyname");
exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("socket");
exit(1);
}

their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(SERVERPORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);


while(1)
{
sleep (1); //1 while making every second
cout << init << endl;
cout << epoch_time << endl;

epoch_time=time(NULL); //updating time
if (init==epoch_time)
{
//packet initialization
packet.id=ID;
packet.send_time=epoch_time;
packet.ACK=0;
packet.recv_time=0;

packets.push_back (packet); //put the packet in the list

ID++;

memcpy(&buffer, &packet, sizeof(packet));

if ((numbytes=sendto(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&their_addr, sizeof their_addr)) == -1)
{
perror ("sendto");
exit(1);
}

printf("sent %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr));

init=epoch_time+5;
}

flags |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flags);
// if (buffer[0] != 0xff)
// {
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buffer, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1)
{
perror ("recvfrom");
exit(1);
}

buffer[numbytes] = '\0';
memcpy(&packet, &buffer, sizeof(buffer));

epoch_time = time( NULL );
packet.recv_time=epoch_time;

for (it=packets.begin(); it != packets.end(); it++)
{
if ((packet.recv_time - it->send_time)<10 && it->id==packet.id)
{
success << "Package " << packet.id << " was successfully received (delay = " << packet.recv_time - it->send_time << ")\n" << endl;
packets.erase(it); //apaga o pacote da lista
break;
}
if ((packet.recv_time - it->send_time)>=10 && it->id==packet.id)
{
dropped << "Package " << packet.id << " was dropped (delay = " << packet.recv_time - it->send_time << ")\n" << endl;
packets.erase(it); //apaga o pacote da lista
break;
}
}

printf("packet contains ID %.2d\n",packet.id);
printf("packet contains ACK %.2d\n",packet.ACK);
// }

if (ID==10)
{
success.close();
dropped.close();
}

}
close(sockfd);

return 0;
}

Last edited by fneves; 11-23-2010 at 08:51 AM.
 
Old 11-22-2010, 04:24 PM   #2
JohnGraham
Member
 
Registered: Oct 2009
Posts: 467

Rep: Reputation: 139Reputation: 139
Quote:
Code:
int flags = fcntl(sockfd, F_GETFL);
flags |= O_NONBLOCK;
fcntl(sockfd, F_SETFL, flags);

if ((he=gethostbyname(argv[1])) == NULL) // get the host info
{
    herror("gethostbyname");
    exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
    perror("socket");
    exit(1);
}
Note that you can use code tags (the #-button just above the text box you write your post in) to make code much easier to read.

Also, you should only use fcntl on a valid file descriptor.

Also, you can use SOCK_NONBLOCK like this when you open the socket to get what you want without having to clutter your code with fnctl code:

Code:
sockfd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0)
 
Old 11-23-2010, 09:26 AM   #3
fneves
LQ Newbie
 
Registered: Nov 2010
Posts: 8

Original Poster
Rep: Reputation: 4
Hi. Many thanks for your reply. I have another problem now. My two ifs (when I print and keep the package well received in a text file based on the delay), in the first packages work well, but from the pack 4 or 5 (depends) fails to enter into this if (successes). Another problem is that packets never enter the second if.

Another problem I see that once worked well (with the blocking prints "1") and now it didnt't work, is the variable ACK coming from the server with "0". Why?

I don't know where I can put the #, but the code that I implemented is (sorry for the tags)

Many thanks again.

Quote:
/*
** talker.c -- a datagram "client" demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define SERVERPORT 4950 // the port users will be connecting to


#define MAXBUFLEN 100

#include <time.h>
#include <iostream>
#include <list>
#include <fstream>


typedef struct
{
int id;
int send_time; //send time
int ACK;
int recv_time; //receive time
} myPacket;

int main(int argc, char *argv[])
{
using namespace std;

int sockfd;
struct sockaddr_in their_addr; // connector's address information
struct hostent *he;
int numbytes;
int ID=1;

time_t init;
socklen_t addr_len;

myPacket packet;
unsigned char buffer[sizeof(packet)];

time_t epoch_time;
epoch_time = time( NULL ); //time in seconds (since 1 Jan 1970)
init=epoch_time+5;

list<myPacket> packets; //list of packets
list<myPacket>::iterator it;

ofstream success;
ofstream dropped;
success.open ("Success.txt");
dropped.open ("Dropped.txt");


if ((he=gethostbyname(argv[1])) == NULL) // get the host info
{
herror("gethostbyname");
exit(1);
}

if ((sockfd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
{
perror("socket");
exit(1);
}

their_addr.sin_family = AF_INET; // host byte order
their_addr.sin_port = htons(SERVERPORT); // short, network byte order
their_addr.sin_addr = *((struct in_addr *)he->h_addr);
memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero);


while(1)
{
//sleep (1); //1 while making every second
cout << init << endl;
cout << epoch_time << endl;

epoch_time=time(NULL); //updating time
if (init==epoch_time)
{
//packet initialization
packet.id=ID;
packet.send_time=epoch_time;
packet.ACK=0;
packet.recv_time=0;

packets.push_back (packet); //put the packet in the list

ID++;

memcpy(&buffer, &packet, sizeof(packet));

if ((numbytes=sendto(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr *)&their_addr, sizeof their_addr)) == -1)
{
perror ("sendto");
exit(1);
}

printf("sent %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr));

init=epoch_time+5;
}


addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buffer, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) != -1)
{
buffer[numbytes] = '\0';
memcpy(&packet, &buffer, sizeof(buffer));

epoch_time = time( NULL );
packet.recv_time=epoch_time;

for (it=packets.begin(); it != packets.end(); it++)
{
if ((packet.recv_time - it->send_time)<8 && it->id==packet.id)
{
success << "Package " << packet.id << " was successfully received (delay = " << packet.recv_time - it->send_time << "s)\n" << endl;
printf("packet contains ID %.2d\n",it->id);
printf("packet contains ACK %.2d\n",it->ACK);
packets.erase(it); //apaga o pacote da lista
break;
}
if ((packet.recv_time - it->send_time)>=8 && it->id==packet.id)
{
dropped << "Package " << packet.id << " was dropped (delay = " << packet.recv_time - it->send_time << "s)\n" << endl;
packets.erase(it); //apaga o pacote da lista
break;
}
}

}

if (ID==7)
{
success.close();
dropped.close();
}

}
close(sockfd);

return 0;
}






/*
** listener.c -- a datagram sockets "server" demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define MYPORT 4950 // the port users will be connecting to

#define MAXBUFLEN 100

typedef struct
{
int id;
int send_time; //send time
int ACK;
int recv_time; //receive time
} myPacket;

int main(void)
{
int sockfd;
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
socklen_t addr_len;
int numbytes;

myPacket packet;
unsigned char buf[sizeof(packet)];

if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("socket");
exit(1);
}

my_addr.sin_family = AF_INET; // host byte order
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);

if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof my_addr) == -1)
{
perror("bind");
exit(1);
}


while (1)
{
sleep(8);
addr_len = sizeof their_addr;
if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1)
{
perror("recvfrom");
exit(1);
}

printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
printf("packet is %d bytes long\n",numbytes);
buf[numbytes] = '\0';
memcpy(&packet, &buf, sizeof(buf));
printf("packet contains %.2d\n",packet.id);

packet.ACK=1; //guarda a informação do tempo de quando chega o pedido do client

memcpy(&buf, &packet, sizeof(packet));

if ((numbytes = sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&their_addr, sizeof their_addr)) == -1)
{
perror ("sendto");
exit(1);
}
}


close(sockfd);

return 0;
}

Last edited by fneves; 11-23-2010 at 09:29 AM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
issue while receving data on IPV6 socket using select,recvfrom nagendrar Programming 1 01-19-2010 04:28 AM
problem with recvfrom saheelahamed Linux - Networking 1 08-28-2007 03:10 PM
Problem in recvfrom() live_dont_exist Programming 5 05-08-2005 04:25 PM
problem with socket() function marri Programming 9 09-14-2004 07:59 PM
timing function calls in C? (recvfrom() on Pentium II) pingswept Programming 4 05-24-2004 07:55 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:17 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration