Normal packet-reception ratio for TCP/IP - tcp

I have an experiment set-up using two laptop machines , one acting as a transmitter and another as receiver. The transmitter continuously transmits packets of different sizes , depending on the time period of different timers that have been configured. The receiver captures these packets and calculates the PRR upon termination of the program.
The transmitter and receiver are separated by a distance of about just 6-7 feet
Is a packet-reception ratio of 0.87 normal for this TCP/IP set-up or is it on the lower side?
Transmitter:
void sendMedicalStream(void) {
timer_count ++;
if(timer_count % 5 ==0) {
memcpy(pu8 ,(struct pulse_oxim_packet*)& oxim_packet , sizeof(struct
pulse_oxim_packet));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count % 50 == 0) {
memcpy(pu8 ,(struct ecg_data*)& wifi_ecg_data , sizeof(struct ecg_data));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count % 10 == 0) {
memcpy(pu8 ,(struct resp_monitor_packet*)& rsp_mon_packet , sizeof(struct
resp_monitor_packet));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count % 120 == 0) {
memcpy(pu8 ,(struct self_check_glucose_monitor_packet*)& gm_packet , sizeof(struct
self_check_glucose_monitor_packet));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count % 30 == 0) {
memcpy(pu8 ,(struct self_check_weight_monitor*)& wm_packet , sizeof(struct
self_check_weight_monitor));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count % 25 == 0) {
memcpy(pu8 ,(struct asthma_monitor*)& as_mon_packet , sizeof(struct asthma_monitor));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count % 35 == 0) {
memcpy(pu8 ,(struct sc_blood_press_mon_packet*)& bp_mon_packet , sizeof(struct
sc_blood_press_mon_packet));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count % 45 == 0) {
memcpy(pu8 ,(struct insulin_pump_packet*)& ins_pump_packet , sizeof(struct
insulin_pump_packet));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count % 15 == 0) {
memcpy(pu8 ,(struct fetal_heart_monitor *)& fhm_packet , sizeof(struct
fetal_heart_monitor));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count % 180 == 0) {
memcpy(pu8 ,(struct dialysis_machine *)& dial_mach_packet , sizeof(struct
dialysis_machine));
x=send(s,pu8,sizeof(u8aSendBuffer),0);
}
if(timer_count == 10000)
timer_count = 0;
}
int main(int argc,char **argv)
{
struct sockaddr_in sin;
/* Packet Title DEtails */
strcpy(fhm_packet.title,"Fetal-Heart-Rate-Monitor");
strcpy(bp_mon_packet.title,"Blood-Pressure-Monitor");
strcpy(ins_pump_packet.title,"Insulin-Pump-Monitor");
strcpy(wm_packet.title,"Weight-Monitor");
strcpy(as_mon_packet.title,"Asthma-Monitor");
strcpy(gm_packet.title,"Glucose-Level-Monitor");
strcpy(rsp_mon_packet.title,"Infant-Respiratory-Monitor");
strcpy(dial_mach_packet.title,"Dialysis-Machine");
/* Socket Details */
len=sizeof(struct sockaddr);
if(argc==2){
host =argv[1];
}
/* translates the host name into peer's IP address */
hp=gethostbyname(host);
if(!hp){
fprintf(stderr,"duplex-talk : uknown host : %s\n",host);
exit(1);
}
/* build address data structures */
bzero((char *)&sin, sizeof(sin));
sin.sin_family = AF_INET;
bcopy(hp->h_addr,(char *)(&sin.sin_addr),hp->h_length);
sin.sin_port = htons(SERVER_PORT);
/* active open */
if((s = socket(PF_INET,SOCK_STREAM,0))<0) {
perror("duplex-talk : socket");
exit(1);
}
if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) <0) {
perror("duplex-talk : connect");
exit(1);
}
/* Timer Details */
struct itimerval it_val; /* for setting itimer */
if (signal(SIGALRM, (void (*)(int)) sendMedicalStream) == SIG_ERR) {
perror("Unable to catch SIGALRM");
exit(1);
}
it_val.it_value.tv_sec = MIN_INTERVAL/1000;
it_val.it_value.tv_usec = (MIN_INTERVAL*1000) % 1000000;
it_val.it_interval = it_val.it_value;
if (setitimer(ITIMER_REAL, &it_val, NULL) == -1) {
perror("error calling ECG setitimer()");
exit(1);
}
/* main loop : get and send lines of text */
int i=0,j=0;
while(1);
}
Receiver :
int main(int argc,char *argv)
{
char * pu8 = u8aSendBuffer;
signal(SIGINT,INThandler);
struct sockaddr_in sin;
struct sockaddr addr;
socklen_t fromlen;
char buf[MAX_LINE];
len=sizeof(struct sockaddr);
/* build address data structues */
bzero((char *)&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(SERVER_PORT);
/* setup passive open*/
if((s=socket(PF_INET,SOCK_STREAM,0))<0) {
perror("duplex-talk:socket");
exit(1);
}
if((bind(s,(struct sockaddr *)&sin, sizeof(sin))) < 0){
perror("duplex-talk: bind");
exit(1);
}
// listen
listen(s,MAX_PENDING);
if((new_s = accept(s,(struct sockaddr *)&sin, &len)) < 0) {
perror("duplex-talk : accept");
exit(1);
}
while(1)
{
recv(new_s,pu8,sizeof(u8aSendBuffer),0);
p_ptr = (struct pulse_oxim_packet *)pu8;
ecg_ptr = (struct ecg_data *)pu8;
resp_mon_ptr = (struct resp_monitor_packet *)pu8;
gmon_ptr = (struct self_check_glucose_monitor_packet *)pu8;
wmon_ptr = (struct self_check_weight_monitor *)pu8;
asmon_ptr = (struct asthma_monitor *)pu8;
bp_mon_ptr = (struct sc_blood_press_mon_packet *)pu8;
ins_pump_packet = (struct insulin_pump_packet *)pu8;
ft_mon_ptr = (struct fetal_heart_monitor *) pu8;
dial_mach_ptr = (struct dialysis_machine *) pu8;
if( p_ptr != NULL && strcmp(p_ptr->title,"Pulse-Oximeter-Data") == 0)
recv_count++;
if( ecg_ptr != NULL && strcmp( ecg_ptr->title,"ECG-Monitor-Data") == 0 )
recv_count++;
if( gmon_ptr != NULL && strcmp( gmon_ptr->title,"Glucose-Level-Monitor") == 0 )
recv_count++;
if( asmon_ptr != NULL && strcmp( asmon_ptr->title,"Asthma-Monitor") == 0 )
recv_count++;
if(wmon_ptr != NULL && strcmp( wmon_ptr->title,"Weight-Monitor") == 0 )
recv_count++;
if( ins_pump_packet != NULL && strcmp( ins_pump_packet->title,"Insulin-Pump-Monitor")
== 0)
recv_count++;
if( bp_mon_ptr != NULL && strcmp(bp_mon_ptr->title,"Blood-Pressure-Monitor") == 0 )
recv_count++;
if( ft_mon_ptr != NULL && strcmp( ft_mon_ptr->title,"Fetal-Heart-Rate-Monitor") == 0 )
recv_count++;
if( dial_mach_ptr != NULL && strcmp( dial_mach_ptr->title,"Dialysis-Machine") == 0 )
recv_count++;
}
return 0;
}

I'm not a networking expert, but if your transmitter is continuously transmitting packets, it's quite possibly introducing far more interference with ACK packets than would normally be the case.
My guess is that if you modify it very slightly so that it doesn't saturate the connection, you'll find you get a much higher packet reception ratio.
EDIT: Having seen your code, I believe one possible problem is that even though you've created a stream-based socket, you're not treating it as one - you're assuming that you'll get exactly one packet on each recv call:
recv(new_s,pu8,sizeof(u8aSendBuffer),0);
You should be using the return value from recv to see how many bytes have actually been received.
It's possible that you're semi-okay to ignore it in this case due to having a very small receiving window (I don't know what sizeof(u8aSendBuffer) is) but in generally you should not be treating the stream as a sequence of packets like you are: you should treat it as a stream of data, where you may or may not receive as much data as you ask for.

Related

Why nghttp2_session_mem_recv does not call any callback? (language: C, library: nghttp2)

ssize_t readlen;
struct evbuffer *input = bufferevent_get_input(bev);
size_t datalen = evbuffer_get_length(input);
unsigned char *data = evbuffer_pullup(input, -1);
readlen = nghttp2_session_mem_recv(session, data, datalen);
if (readlen < 0) {
printf("Fatal error: %s\n", nghttp2_strerror((int)readlen));
return;
}
if (evbuffer_drain(input, (size_t)readlen) != 0) {
printf("Fatal error: evbuffer_drain failed\n");
return;
}
nghttp2_session_mem_recv function does not call any callback even though it has all the callbacks set and the result returned by it is a valid one (return 130 and datalen is also 130).

Can we run a Multi Socket Client and each client in thread in QNX C

I'm working on the project where all 3 devices are running in QNX
2 Socket Client (non blocking) running in One CPU., remaining 2 CPU are running as Server.
When I test run, I see some issues with Client don't receive reply from the Server for certain time, then I have to drop the connection and re-establish.
I have doubt that there are any restriction under the same process, 2 client socket thread can not be running? esp in QNX. If so how to create the process and create the thread on the process for each client.
// Client Side Code
int CNoseCapUnitECUCLient::iStartTCPIPHandler(eNCUOption eOption)
{
printf("Start %s NCU TCPIP Handler handler \n",(meNCUOption == NCU_FREE_AREA) ? "Local":"Remote" );
meNCUOption = eOption;
if(mbTCPHandThreadAlive)
{
iStopTCPIPHandler();
}
else
{
iCreateMutex(mpMainMutex, "TCPIPMutex");
}
// Create new handler thread
mpHandThread = CMNcreateThread();
if(mpHandThread == nullptr)
{
return 1;
}
// Thread priority should at least be equal to LTA application (21)
bool bResult = mpHandThread->create("TCP_HeartbeatThread", 0, 0, 0, &heartBeatThread, this);
if(bResult == false)
{
return 1;
}
mbHandling = true;
mbTCPHandThreadAlive = true;
return EOK;
}
void CNoseCapUnitECUCLient::TCP_HeartbeatThread()
{
int iRecvLen = 0;
unsigned char buf = 55;
strcpy( (char*) Sendbuf, " ECU->NCU Heartbeat\n " );
while(1)
{
CMNOSSleep(1);
mpMainMutex->take(200);
if(!ConnectedToServer)
{
CMNOSSleep(1000); // delay after the connection.
if(connectToNCU())
{
LastRecvTime = localClock_t::now();
ConnectedToServer = true;
}
}
else if(ConnectedToServer)
{
if(std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastSendTime).count() > 50) // HeartBeat
{
SendNCUCommand(msgSetTimerHeartbeat,MSG_NONE, &buf , 1);
}
else
{
strcpy((char*)ucRecvBuf,"");
iRecvLen = recvResponse(ucRecvBuf);
if( iRecvLen > 0)
{
if(strlen((char*)ucRecvBuf) > 0)
{
iRecvError = 0;
if(commState == false)
{
iSetBrightness(LCD_BRIGHTNESS_100PERCENT);
onCommunication(true);
}
ClientRxChar((char*)ucRecvBuf, iRecvLen);
}
}
else if(iRecvLen == 0)
{
iRecvError++;
if(iRecvError >= 5)
{
iRecvError = 0;
}
}
else if(iRecvLen == -1)
{
printf(" ****client Recv Function return false ***** \n" );
iRecvError = 0;
ConnectedToServer = false;
disconnect();
onCommunication(false);
}
}
if(std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count() > 5000) //
{
printf(" **** NO Comm for 7 seconds ***** \n" );
iRecvError = 0;
ConnectedToServer = false;
disconnect();
onCommunication(false);
}
else
{
//printf(" recv time %s %d %d \n " ,(meNCUOption == NCU_FREE_AREA) ? "Local":"Remote",
// std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count(), (localClock_t::now() - LastRecvTime).count());
}
ScanReceivedData(); // scan and call the corresponding function
}
mpMainMutex->release();
}
}
Server Side Code
void CNosecapTCPIPServer::ServerInit(int port)
{
portno = port;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd < 0)
{
printf("ERROR opening socket \n");
}
optval = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,
&optval , sizeof(int));
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons((unsigned short)portno);
if (bind(listenfd, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
{
m_errorCode = errno;
snprintf(m_errorMsg, 128, "%s", strerror(m_errorCode));
printf("ERROR on binding : %s \n", m_errorMsg );
}
printf("listen \n");
if (listen(listenfd, 5) < 0)
{
m_errorCode = errno;
snprintf(m_errorMsg, 128, "%s", strerror(m_errorCode));
printf("ERROR on listen %s \n", m_errorMsg);
}
clientlen = sizeof(clientaddr);
//fcntl(listenfd, F_SETFL, O_NONBLOCK);
}
void CNosecapTCPIPServer::TCP_HeartbeatThread()
{
while(1)
{
usleep(1000);
//takeMutex(50);
if(!ConnectedToClient)
{
//fcntl(listenfd, F_SETFL, O_NONBLOCK);
// accept: wait for a connection request
connfd = accept(listenfd, (struct sockaddr *) &clientaddr, &clientlen);
if (connfd < 0)
{
}
else
{
lockMutex();
//fcntl(connfd, F_SETFL, O_NONBLOCK); // blocking mode
ConnectedToClient = true;
LastRecvTime = localClock_t::now();
printCurenttime();
sprintf(printBuf, "Server established connection (log) \n ");
onLogMessage(printBuf);
unlockMutex();
}
}
else if(ConnectedToClient)
{
//// accept: wait for a connection request
if(connfd > 0)
{
strcpy((char*)buf,"");
n = recv(connfd, buf, ***5000***,0 ); // used recv instead of read.
//printf("recv connfd %d n = %d errno = %d \n", connfd, n, errno);
if (n <= 0)
{
if( n < 0 && errno != 11)
{
//disconnect();
//continue;
sprintf(printBuf, "Read Error n (%d) socket (%d) error (%d)\n",n, connfd , errno);
onLogMessage(printBuf);
}
if(n == 0)
{
//LastRecvTime = localClock_t::now();
}
}
else
{
lockMutex();
LastRecvTime = localClock_t::now();
ServerRxChar(buf, n); // Update to the serialNessageQ
SendECUCommand(msgSetTimerHeartbeat,MSG_NONE, (unsigned char*)buf+8, 1);
if(commState == false)
{
updateCommunicationStatus(true);
}
unlockMutex();
}
}
}
//unlockMutex();
}
}
void CNosecapTCPIPServer::TCP_BufferHandleThread()
{
while(1)
{
takeMutex(30);
ScanReceivedData(); // scan and call the corresponding function
if(ConnectedToClient)
{
if(std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count() > 8000) //
{
sprintf(printBuf, " \t\t (1) Not Reveived more than 10 secs : %d (%d) \n", (localClock_t::now() - LastRecvTime).count(),
std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count());
onLogMessage(printBuf);
LastRecvTime = localClock_t::now();
if(setTimeCommand == false)
disconnect();
}
else
{
//printf("\t\t (1)last recv %d (%d) \n",std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count(),
// (localClock_t::now() - LastRecvTime).count());
if(setTimeCommand)
setTimeCommand = false;
}
}
unlockMutex();
usleep(1000);
}
}
bool CNosecapTCPIPServer::SendCommand(void *pucCommand, int iLength)
{
int n;
unsigned char tp[200];
memcpy(tp, pucCommand, 200);
if(connfd)
{
n = write(connfd, pucCommand, iLength);
if (n < 0)
{
printf(" ERROR writing to socket (%d) error (%d) \n", connfd , errno);
sprintf(printBuf , " ERROR writing to socket (%d) error (%d) \n", connfd , errno);
onLogMessage(printBuf);
//disconnect();
//continue;
}
}
return true;
}

Convert a string from UART to hex value in c

I am working on pic controllers. I have a string "040F" which is sent to the controller through UART.
I want to convert this string to a hex representation such as 0x040F. I tried a code snippet but no success.
Can anyone please help me out.
If what you mean is to convert a hex string to binary, the below code can help. It may not be an optimized one and may be other simpler solutions are available in the internet and can be even buggy. But it will give you some idea, I hope.
#include<stdio.h>
#include<string.h>
#define MAX_STR_LEN 16
int hex_char_to_bin(char ch)
{
if(ch >= '0' && ch <= '9')
{
return (ch - '0');
}
else if(ch >= 'a' && ch <= 'f')
{
return (10 + ch - 'a');
}
else if(ch >= 'A' && ch <= 'F')
{
return (10 + ch - 'A');
}
return -1;
}
int hex_str_to_bin(const char *hex_str, int *result)
{
int str_len, i;
int bin_val = 0;
str_len = strnlen(hex_str, MAX_STR_LEN);
for (i = 0; i < str_len; i++)
{
int val = hex_char_to_bin(*hex_str++);
if (val == -1)
return -1;
bin_val = (bin_val<<4) + val;
}
*result = bin_val;
return 0;
}
int main()
{
char str[] = "043f";
int hex;
if(!hex_str_to_bin(str, &hex))
printf("%x\n",hex);
else
printf("Invalid hex charecters in string\n");
return 0;
}

C - IPC semaphores with fork

I'm having a problem with following program:
What it was supposed to do:
First child process should get a number from STDIN and set it to shared variable.
Second child process should read number from shared variable and print it binary on STDOUT.
What it does:
It never asks for a number, after running it, it just prints inifnite number of zero's. It looks like it jumps straight away into a second child and never leaves it.
Code:
#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
/* jest zdefiniowane w sys/sem.h */
#else
union semun
{
int val;
struct semid_ds* buf;
unsigned short int* array;
struct seminfo* __buf;
};
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <fcntl.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/mman.h>
//shared
static int *glob_var;
struct sembuf operacja;
void operacjaSem(int, int, int);
int main(void)
{
/*---------------------------------------*/
//shared memory
glob_var = mmap(NULL, sizeof(*glob_var), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
/*---------------------------------------*/
//semafory
key_t klucz;
int semafor;
union semun ustaw;
//tworze jednoznaczny klucz dla semaforow
if((klucz = ftok(".", 'B')) == -1)
{
fprintf(stderr, "blad tworzenia klucza\\n");
exit(1);
}
//stworzenie semaforow
if((semafor = semget(klucz, 2, IPC_CREAT | IPC_EXCL | 0600)) == -1)
{
fprintf(stderr, "blad tworzenia semaforow\\n");
exit(1);
}
//inicjacja semaforow
ustaw.val = 1;
if(semctl(semafor, 0, SETVAL, ustaw) == -1)
{
fprintf(stderr, "blad ustawienia semafora0\\n");
exit(1);
}
ustaw.val = 0;
if(semctl(semafor, 1, SETVAL, ustaw) == -1)
{
fprintf(stderr, "blad ustawienia semafora1\\n");
exit(1);
}
if(fork() == 0)
{
//first child process
while(1)
{
if(semctl(semafor, 0, GETVAL) == 1)
{
//ustawiam zmienna wspoldzielona
char buf2[128];
fgets(buf2, 128, 0);
*glob_var = atoi(buf2);
//printf("buf: %d", *glob_var);
//przestawiam semafory
operacjaSem(semafor, 0, -1);
operacjaSem(semafor, 1, 1);
}
}
}
if(fork() == 0)
{
//second child process
while(1)
{
if(semctl(semafor, 1, GETVAL) == 1)
{
operacjaSem(semafor, 1, -1);
//odczytuje i wypisuje
int x = *glob_var;
int p[32];
for(int z = 0; z < 32; z++)
{
if(x % 2 == 1 || x % 2 == -1) p[z] = 1;
else p[z] = 0;
x = x >> 1;
}
for(int z = 31; z >= 0; z--)
printf("%d", p[z]);
printf("\n");
//przestawiam semafory
operacjaSem(semafor, 1, -1);
operacjaSem(semafor, 0, 1);
}
}
}
return 0;
}
void operacjaSem(int semafor, int nr, int op)
{
operacja.sem_num = nr;
operacja.sem_op = op;
operacja.sem_flg = 0;
if(semop(semafor, &operacja, 1) == -1)
{
fprintf(stderr, "blad operacji na semaforze\\n");
exit(1);
}
}
Change the first line that reads:
if(fork() == 0)
To something like
pid_t processID = fork();
if(processID == 0)
Change the second line that reads
if(fork() == 0)
To an else. More explicitly, for that second line, change:
}
if(fork() == 0)
{
//second child process
To:
}
else
{
if (processID < 0) {
printf ("Fork error\n"); exit(-1);
}
//second child process
And probably if the rest of your code is OK, it will start working. At least this will get your forks in good shape so you can keep working with the rest of the code.

How to measure the time of transferring a file from the server to the client?

I want to measure the time of transferring a file from the send to the recv by the PGM/UDP protocol. Actually , I try to use clock() function to measure the execution time of both the send and recv program ,but it seems to be incorrect. What should I do to measure the time of transferring a file ?
Here is the code :
clock_t t = clock();
do
{
struct timeval tv;
size_t len;
int timeout;
pgm_error_t *pgm_err = NULL;
const int status = pgm_recv (rx_sock,
buf,
sizeof(buf),
0,
&len,
&pgm_err);
switch (status)
{
case PGM_IO_STATUS_NORMAL:
/* receive file */
if (len < 30)
{
strncpy(newFile, buf, len);
if (0 == strncmp(newFile, testNewFile, len))
{
flag = 1;
continue;
}
strncpy(endFile, buf, len);
if (0 == strncmp(endFile, testEndFile, len))
{
//g_quit = 1;
t = clock() -t;
printf("%s takes time: %f\n", fileName, ((float)t) / CLOCKS_PER_SEC);
continue;
}
}
if (flag == 1)
{
strncpy(fileName, buf, len);
// puts(fileName);
fp = fopen(fileName, "wb");
g_assert(fp);
flag = 0;
}
else
num_read = fwrite (buf, sizeof(char), len, fp);
break;
case PGM_IO_STATUS_TIMER_PENDING:
{
socklen_t optlen = sizeof (tv);
pgm_getsockopt (rx_sock, IPPROTO_PGM, PGM_TIME_REMAIN, &tv, &optlen);
}
goto block;
case PGM_IO_STATUS_RATE_LIMITED:
{
socklen_t optlen = sizeof (tv);
pgm_getsockopt (rx_sock, IPPROTO_PGM, PGM_RATE_REMAIN, &tv, &optlen);
}
case PGM_IO_STATUS_WOULD_BLOCK:
block:
timeout = PGM_IO_STATUS_WOULD_BLOCK == status ? -1 : ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
memset (fds, 0, sizeof(fds));
fds[0].fd = g_quit_pipe[0];
fds[0].events = POLLIN;
pgm_poll_info (rx_sock, &fds[1], &n_fds, POLLIN);
poll (fds, 1 + n_fds, timeout);
break;
default:
if (pgm_err)
{
g_warning ("%s", pgm_err->message);
pgm_error_free (pgm_err);
pgm_err = NULL;
}
if (PGM_IO_STATUS_ERROR == status)
break;
}
}while (!g_quit);
fclose (fp);
return NULL;

Resources