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
Welcome to
LinuxQuestions.org , a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free.
Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please
contact us . If you need to reset your password,
click here .
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a
virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month.
Click here for more info.
11-22-2010, 02:36 PM
#1
LQ Newbie
Registered: Nov 2010
Posts: 8
Rep:
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 .
11-22-2010, 04:24 PM
#2
Member
Registered: Oct 2009
Posts: 467
Rep:
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)
11-23-2010, 09:26 AM
#3
LQ Newbie
Registered: Nov 2010
Posts: 8
Original Poster
Rep:
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 .
All times are GMT -5. The time now is 03:47 PM .
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know .
Latest Threads
LQ News