LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 05-27-2011, 06:49 AM   #1
nwpuhlh
LQ Newbie
 
Registered: Apr 2010
Location: hangzhou, china
Distribution: Fedora 13
Posts: 9

Rep: Reputation: 0
Code analysis: Why Receiver have to wait for 2s?


Hi,

When I'm learning programing of UDP communication on Linux, I found a problem which I could not explain.

Here is what I'm meant to do:
1) Setup UDP listener in main thread and print out what it got;
2) Create a timer in main thread and also set a TimerExpiration Callback to send Pkt periodicially.

The problem is that after Callback send out the Pkt Receiver have to wait for 2s, which is also the interval for the timer, to get the data. But I think there should be not the delay between TX&RX. Could you help tell me why? Thanks!

Here is log:

# ./a.out
Timer is created successfully!
Timer is armed successfully!

[6143832.567283768]Thread_3087104912_Sent 6 bytes to 127.0.0.1
[6143832.567353744]Thread_3087107776_Received pkt from peer: 127.0.0.1
Msg content: 0x34 0x12 0x78 0x56 0x21 0x90
[6143834.567262533]Thread_3087107776_Received pkt from peer: 127.0.0.1
Msg content: 0x34 0x12 0x78 0x56 0x21 0x90


[6143834.567345105]Thread_3087104912_Sent 6 bytes to 127.0.0.1
[6143836.567255395]Thread_3087107776_Received pkt from peer: 127.0.0.1
Msg content: 0x34 0x12 0x78 0x56 0x21 0x90

[6143836.567337518]Thread_3087104912_Sent 6 bytes to 127.0.0.1
[6143838.567255424]Thread_3087107776_Received pkt from peer: 127.0.0.1
Msg content: 0x34 0x12 0x78 0x56 0x21 0x90

[6143838.567337250]Thread_3087104912_Sent 6 bytes to 127.0.0.1

Code is here: (gcc UDP_server_client.c -Wall -lrt)

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>

#define UDP_SERVER_PORT 60000
#define BUF_DEPTH 200

timer_t timer_id;

char* show_msg_content(char *ptr, unsigned short len)
{
static char buf[100];
int rtn=0;
int char_printed=0;
int i=0;

for (i=0; i<len; i++)
{
rtn = snprintf(&buf[char_printed], (sizeof(buf)-char_printed), "0x%X ", *((unsigned char *)(ptr+i)));
if (rtn < 0)
{
printf("buf overflow! \n");
return NULL;
}
else
{
char_printed += rtn;
}
}

return buf;

}

void send_pkt(union sigval val)
{
int result;

static short msg[]={0x1234, 0x5678, 0x9021};
int sending_sockfd; /* file descriptor of the sending socket */
struct sockaddr_in peer_addr; /* connector's address information */
int numbytes;

sending_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == result)
{
printf ("Failed to create Sender socket, err_no %d\n", errno);
return;
}

/* sending_sockfd not initialized, which means sys will choose one port to send pkt? */

peer_addr.sin_family = AF_INET; /* Host byte order */
peer_addr.sin_port = htons(UDP_SERVER_PORT); /* Short, network byte order */
peer_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); /* Set to local ip addr */
bzero(&(peer_addr.sin_zero), 8); /* Zero the rest of the struct */

numbytes = sendto(sending_sockfd, (unsigned char *)msg, sizeof(msg), 0, (struct sockaddr *)&peer_addr, sizeof(struct sockaddr));

if (numbytes>0)
{
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
printf("\n[%d.%ld]Thread_%lu_Sent %d bytes to %s\n", (unsigned int)(tp.tv_sec), tp.tv_nsec, (unsigned long int)(pthread_self()), numbytes, inet_ntoa(peer_addr. sin_addr )) ;
}

close ( sending_sockfd ) ;
}

int main ()
{
int result=0;
struct sigevent sig_en;

/* Setup a timer and arm it */
memset((char *)&sig_en, 0, sizeof (sig_en));
sig_en.sigev_notify = SIGEV_THREAD;
sig_en.sigev_notify_function = &send_pkt;

result = timer_create(CLOCK_MONOTONIC, &sig_en, &timer_id);

if (0 == result)
{
printf("Timer is created successfully!\n");
}
else
{
printf("Timer failed to be created!\n");
}

struct itimerspec new_value, old_value;
/* Initial expiration */
new_value.it_value.tv_sec = 2;
new_value.it_value.tv_nsec = 0;
/* each time an armed timer expires, the timer is reloaded from the value specified in new_value->it_interval */
new_value.it_interval.tv_sec = new_value.it_value.tv_sec;
new_value.it_interval.tv_nsec = new_value.it_value.tv_nsec;

result = timer_settime(timer_id, 0, &new_value, &old_value);

if (0 == result)
{
printf("Timer is armed successfully!\n");
}
else
{
printf("Timer failed to be armed!\n");
}

/* Setup UDP server */
int recv_sockfd; /* Receiver's sockfd */
struct sockaddr_in my_addr; /* My address information */
struct sockaddr_in peer_addr; /* Peer's address information */
unsigned int addr_len;
int numbytes;

char recv_buf[BUF_DEPTH];

/* Create UDP IPV4 socket */
recv_sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (-1 == recv_sockfd)
{
printf ("Failed to create Receiver socket, err_no %d\n", errno);
return -1;
}

/* Init my_addr */
my_addr.sin_family = AF_INET; /* IPV4, host byte order */
my_addr.sin_port = htons(UDP_SERVER_PORT); /* Short, network byte order */
my_addr.sin_addr.s_addr = INADDR_ANY; /* Auto-fill with my IP */
bzero(&(my_addr.sin_zero), 8); /* Zero the rest of the struct */

/* Bind socket with the UDP port */
result = bind(recv_sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));
if (-1 == result)
{
printf ("Failed to bind socket, err_no %d\n", errno);
return -1;
}

/* Receive packet from peer */
addr_len = sizeof(struct sockaddr);
while (1)
{
numbytes = recvfrom(recv_sockfd, recv_buf, BUF_DEPTH, 0, (struct sockaddr *)&peer_addr, &addr_len);
if (numbytes >0)
{
struct timespec tp;
clock_gettime(CLOCK_MONOTONIC, &tp);
printf("[%d.%ld]Thread_%lu_Received pkt from peer: %s\n", (unsigned int)(tp.tv_sec), tp.tv_nsec, (unsigned long int)(pthread_self()), inet_ntoa(peer_addr.sin_addr));
printf("Msg content: %s\n", show_msg_content(recv_buf, numbytes));
}
else
{
printf("Error when recvfrom, err_no %d\n", errno);
}
}

return 0;
}
 
Old 05-27-2011, 07:02 AM   #2
nwpuhlh
LQ Newbie
 
Registered: Apr 2010
Location: hangzhou, china
Distribution: Fedora 13
Posts: 9

Original Poster
Rep: Reputation: 0
Is it possible that main thread and timer thread share a single sem queue...?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
#TwitterWorm Code Analysis Cleaned-up Version mjolnir General 0 09-21-2010 12:18 PM
Looking for tools for static/dynamic code analysis for Linux like2learn Programming 1 09-12-2010 02:15 PM
code analysis for C, C++, Java, Tcl, PHP powah Programming 2 04-21-2005 08:09 PM
How do I code network analysis program.? sebustian Linux - Networking 0 09-19-2004 07:14 AM
C code analysis tools Dark_Helmet Programming 8 07-12-2004 12:27 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 10:50 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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration