Socket datagram

Kartik Subbarao subbarao at phoenix.Princeton.EDU
Tue May 14 23:44:19 AEST 1991


In article <11225 at hub.ucsb.edu> hubert at spica.ucsb.edu writes:
>
>Hi! I am testing the socket's datagram facility and I can't figure
>out why the following program doesn't work. The a.out give me
>error message like "bad address". Could someone explain it ?
>
>By the way,  I just want to use these system call instead of 
>the listen ,accept and connect  for the socket_stream.

[lotsa code deleted]

The reason you're getting bad addresses is because you're specifying a
variable, rather than the address of a variable, for the last parameter 
fromlen. You say:

recvfrom(s2, mesg2, sizeof(mesg2), 0, &sock1, sizeof(sock1));

The "sizeof(sock1)" should be some variable where it STORES the size of the
address that it receives data from. While passing "&sock1", you say that
that is the place to store the address of the next datagram that you
receive. While this is okay in this hackish example because that's the only
sockaddr whose socket you're going to get data from, I don't think you 
understand the purpose of those parameters. You cannot say "I want to
receive the next datagram from sockaddr foo, and you please fill it in".
recvfrom() just returns the next datagram being sent to the specified socket; 
if you want to know who sent it to you, you should create another struct 
sockaddr and pass its address, rather than &sock1. Again, if you want to
know the size of that address, you create another variable, and pass its
address in fromlen.

Here's an example of what I think you were trying to illustrate (with some
error checking deleted):

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>

main()
{
	int s1, s2, len, sz;
	char mesgp[20], mesgc[20], mesgt[20];
	struct sockaddr	sock1, sock2, stemp;

	sock1.sa_family=PF_UNIX; sock2.sa_family=PF_UNIX;
	sprintf(sock1.sa_data,"sock1"); sprintf(sock2.sa_data,"sock2");
	unlink(sock1.sa_data); unlink(sock2.sa_data);

	s2 = socket(PF_UNIX, SOCK_DGRAM,0); bind(s2, &sock2,sizeof(sock2));
	s1 = socket(PF_UNIX, SOCK_DGRAM,0); bind(s1, &sock1,sizeof(sock1));

	sprintf(mesgt,"first");	 /* actually don't need a variable for this */
	if (sendto(s1, mesgt, sizeof(mesgt), 0, &sock2,sizeof(sock2))==-1)
		perror("parent send error");
	
	if (! fork()) {
		printf("child\n");
		if (recvfrom(s2, mesgc, sizeof(mesgc), 0, &stemp, &sz)==-1)
			perror("child receive error");
		else printf("child receives mesg %s\n", mesgc);
		sprintf(mesgt,"second");
		if (sendto(s2, mesgt, sizeof(mesgt),0, &sock1, sizeof(sock1)) == -1)
			perror("child send error");
		exit(0);
	}
	printf("parent\n");
	if (recvfrom(s1, mesgp, sizeof(mesgp), 0, &stemp, &sz) == -1)
		perror("parent receive error");
	else 
		printf("got this from kid: %s\n",mesgp);
	wait(0);
	unlink(sock1.sa_data); unlink(sock2.sa_data);
}


Aren't datagram sockets fun? :-)

		-Kartik

--
internet% ypwhich

subbarao at phoenix.Princeton.EDU -| Internet
kartik at silvertone.Princeton.EDU (NeXT mail)  
SUBBARAO at PUCC.BITNET			          - Bitnet



More information about the Comp.unix.wizards mailing list