linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* how to read one udp packet with more than one recvfrom() calls?
@ 2010-11-08  7:08 ranjith kumar
  2010-11-08  7:12 ` Changli Gao
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: ranjith kumar @ 2010-11-08  7:08 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 582 bytes --]

Hi,

I  have implemented client and server programs using udp
protocol(files are attached).
UDP packet size is 500bytes.

I want to read these 500bytes in two calls to recvfrom(). First time
reading 100bytes and second time 400bytes.
How to do this?

When I tried to change the third argument of recvfrom(size_t len),
from 500 to 100, first 100bytes are read correctly.
But when I call recvfrom() second time with len=400, it is reading the
first 400bytes of "next udp packet".
Why? Isn't it possible to read one udp packet in two calls to
recvfrom()/read()????

Thanks in advance.

[-- Attachment #2: client.c --]
[-- Type: application/octet-stream, Size: 1169 bytes --]

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

#define BUFLEN 500
#define PORT  5000
#define NPACK  5

 
#define SRV_IP "107.109.38.32"
 /* fprintf(stdout,), #includes and #defines like in the server */

 int main(void)
 {
   struct sockaddr_in si_other;
   int s, i, slen=sizeof(si_other);
   char buf[BUFLEN];

   if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
     fprintf(stdout,"socket");

   memset((char *) &si_other, 0, sizeof(si_other));
   si_other.sin_family = AF_INET;
   si_other.sin_port = htons(PORT);
   if (inet_aton(SRV_IP, &si_other.sin_addr)==0) {
     fprintf(stderr, "inet_aton() failed\n");
     exit(1);
   }

   for (i=0; i<NPACK; i++) {
     printf("Sending packet %d\n", i);
     sprintf(buf, "This is packet %d\n", i);
//	write(s,buf,BUFLEN);
     if (sendto(s, buf, BUFLEN, 0, &si_other, slen)==-1)
      fprintf(stdout,"sendto()");
   }

   close(s);
   return 0;
 }


[-- Attachment #3: server.c --]
[-- Type: application/octet-stream, Size: 1083 bytes --]

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

#define BUFLEN 500
#define PORT  5000
#define NPACK  5



void diep(char *s)
{
	perror(s);
	exit(1);
}

int main(void)
{
	struct sockaddr_in si_me, si_other;
	int s, i, slen=sizeof(si_other);
	char buf[BUFLEN];

	if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
		diep("socket");

	memset((char *) &si_me, 0, sizeof(si_me));
	si_me.sin_family = AF_INET;
	si_me.sin_port = htons(PORT);
	si_me.sin_addr.s_addr = htonl(INADDR_ANY);
	if (bind(s, &si_me, sizeof(si_me))==-1)
		diep("bind");

	for (i=0; i<NPACK; i++) {
		if (recvfrom(s, buf, BUFLEN, 0, &si_other, &slen)==-1)
			diep("recvfrom()");
//	read(s,buf,BUFLEN);
		printf("Received packet from %s:%d\nData: %s\n\n", 
				inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port), buf);
	}

	close(s);
	return 0;
}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: how to read one udp packet with more than one recvfrom() calls?
  2010-11-08  7:08 how to read one udp packet with more than one recvfrom() calls? ranjith kumar
@ 2010-11-08  7:12 ` Changli Gao
  2010-11-08  7:51 ` Michael Tokarev
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Changli Gao @ 2010-11-08  7:12 UTC (permalink / raw)
  To: ranjith kumar; +Cc: linux-kernel

On Mon, Nov 8, 2010 at 3:08 PM, ranjith kumar <ranjithproxy@gmail.com> wrote:
> Hi,
>
> I  have implemented client and server programs using udp
> protocol(files are attached).
> UDP packet size is 500bytes.
>
> I want to read these 500bytes in two calls to recvfrom(). First time
> reading 100bytes and second time 400bytes.
> How to do this?
>
> When I tried to change the third argument of recvfrom(size_t len),
> from 500 to 100, first 100bytes are read correctly.
> But when I call recvfrom() second time with len=400, it is reading the
> first 400bytes of "next udp packet".
> Why? Isn't it possible to read one udp packet in two calls to
> recvfrom()/read()????
>

recvmsg(2):

       MSG_PEEK
              This  flag  causes the receive operation to return data from the
              beginning of the receive queue without removing that  data  from
              the queue.  Thus, a subsequent receive call will return the same
              data.

-- 
Regards,
Changli Gao(xiaosuo@gmail.com)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: how to read one udp packet with more than one recvfrom() calls?
  2010-11-08  7:08 how to read one udp packet with more than one recvfrom() calls? ranjith kumar
  2010-11-08  7:12 ` Changli Gao
@ 2010-11-08  7:51 ` Michael Tokarev
  2010-11-08 18:31 ` Rick Jones
  2010-11-09  5:35 ` Varun Chandramohan
  3 siblings, 0 replies; 5+ messages in thread
From: Michael Tokarev @ 2010-11-08  7:51 UTC (permalink / raw)
  To: ranjith kumar; +Cc: linux-kernel

08.11.2010 10:08, ranjith kumar wrote:
> Hi,
> 
> I  have implemented client and server programs using udp
> protocol(files are attached).
> UDP packet size is 500bytes.
> 
> I want to read these 500bytes in two calls to recvfrom(). First time
> reading 100bytes and second time 400bytes.
> How to do this?

There's no way to do so.  According to the udp(7) manpage:

 All receive operations return only one packet.  When the packet is
 smaller than the passed buffer, only that much data is  returned; when
 it is bigger, the packet is truncated and the MSG_TRUNC flag is set.
 MSG_WAITALL is not supported.

This is intentional, because the kernel does not keep the received
packets, it either delivers them right to the application or drops
them.  There's no sophisticated queue/stream management like for tcp.

For current speeds, one wants to _reduce_ number of system calls
made, not to increase them as you're trying to do, in order to
process as many data in one go as possible.  This is why new
system calls like mrecvfrom are being proposed.

> When I tried to change the third argument of recvfrom(size_t len),
> from 500 to 100, first 100bytes are read correctly.
> But when I call recvfrom() second time with len=400, it is reading the
> first 400bytes of "next udp packet".
> Why? Isn't it possible to read one udp packet in two calls to
> recvfrom()/read()????

This is how UDP is designed to work, and how it works on other
operating systems too.

/mjt

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: how to read one udp packet with more than one recvfrom() calls?
  2010-11-08  7:08 how to read one udp packet with more than one recvfrom() calls? ranjith kumar
  2010-11-08  7:12 ` Changli Gao
  2010-11-08  7:51 ` Michael Tokarev
@ 2010-11-08 18:31 ` Rick Jones
  2010-11-09  5:35 ` Varun Chandramohan
  3 siblings, 0 replies; 5+ messages in thread
From: Rick Jones @ 2010-11-08 18:31 UTC (permalink / raw)
  To: ranjith kumar; +Cc: linux-kernel

ranjith kumar wrote:
> Hi,
> 
> I  have implemented client and server programs using udp
> protocol(files are attached). UDP packet size is 500bytes.
> 
> I want to read these 500bytes in two calls to recvfrom(). First time
> reading 100bytes and second time 400bytes.
> How to do this?

You can't. Certainly not in antyhing remotely portable.  Receipt of a UDP 
datagram is a one-shot proposition - the bytes from the UDP datagram that do not 
fit in the buffer(s) provided in the receive call are discarded.  You might look 
into readv() or recvmsg() if you want to get bytes placed into different buffers.

> When I tried to change the third argument of recvfrom(size_t len),
> from 500 to 100, first 100bytes are read correctly.
> But when I call recvfrom() second time with len=400, it is reading the
> first 400bytes of "next udp packet".
> Why? Isn't it possible to read one udp packet in two calls to
> recvfrom()/read()????

SOCK_DGRAM+UDP provides datagram semantics, not byte-stream semantics.

rick jones

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: how to read one udp packet with more than one recvfrom() calls?
  2010-11-08  7:08 how to read one udp packet with more than one recvfrom() calls? ranjith kumar
                   ` (2 preceding siblings ...)
  2010-11-08 18:31 ` Rick Jones
@ 2010-11-09  5:35 ` Varun Chandramohan
  3 siblings, 0 replies; 5+ messages in thread
From: Varun Chandramohan @ 2010-11-09  5:35 UTC (permalink / raw)
  To: ranjith kumar; +Cc: linux-kernel

try MSG_PEEK option.

Regards,
Varun 

On Monday, November 08, 2010 12:38:47 pm ranjith kumar wrote:
> Hi,
> 
> I  have implemented client and server programs using udp
> protocol(files are attached).
> UDP packet size is 500bytes.
> 
> I want to read these 500bytes in two calls to recvfrom(). First time
> reading 100bytes and second time 400bytes.
> How to do this?
> 
> When I tried to change the third argument of recvfrom(size_t len),
> from 500 to 100, first 100bytes are read correctly.
> But when I call recvfrom() second time with len=400, it is reading the
> first 400bytes of "next udp packet".
> Why? Isn't it possible to read one udp packet in two calls to
> recvfrom()/read()????
> 
> Thanks in advance.
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-11-09  5:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-08  7:08 how to read one udp packet with more than one recvfrom() calls? ranjith kumar
2010-11-08  7:12 ` Changli Gao
2010-11-08  7:51 ` Michael Tokarev
2010-11-08 18:31 ` Rick Jones
2010-11-09  5:35 ` Varun Chandramohan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).