LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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


Reply
  Search this Thread
Old 09-20-2005, 08:43 AM   #1
alaios
Senior Member
 
Registered: Jan 2003
Location: Aachen
Distribution: Opensuse 11.2 (nice and steady)
Posts: 2,203

Rep: Reputation: 45
First pc sends second dont receive (Sockets problem) Help paul


Hi i have a serious serious problem.
I want to send from one pc to an other an array of unions.
The variable is defined as
union qdisc qdisc_stats[10];

The packet is being send with the next system call
if (sendto( sock2, qdisc_stats, sizeof(qdisc_stats), 0, (struct sockaddr *) &server2, server_len2) <0){
perror("Client send to");
close(sock2);
}

I have selected the 8888 port for this job.
Using tcpdump i have checked that the packet is being succesfully generated and received from the other pc

(see the last line)
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
15:55:50.869415 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], length: 196) 192.168.1.11.9997 > 192.168.1.3.9997: UDP, length: 168
15:56:00.870447 IP (tos 0x0, ttl 64, id 24785, offset 0, flags [+], length: 1500) 192.168.1.11.8888 > 192.168.1.3.8888: UDP, length: 4800


I have also checked that the pc that waits for the packet succesfully binds to the port
(check last line)

udp 0 0 192.168.1.3:137 0.0.0.0:* 6818/nmbd
udp 0 0 0.0.0.0:137 0.0.0.0:* 6818/nmbd
udp 0 0 192.168.1.3:138 0.0.0.0:* 6818/nmbd
udp 0 0 0.0.0.0:138 0.0.0.0:* 6818/nmbd
udp 0 0 0.0.0.0:161 0.0.0.0:* 6968/snmpd
udp 0 0 0.0.0.0:8888 0.0.0.0:* 27120/3threads




But still the packet dont seem to be received from the programme at all
(Firewalls are closed.. Everything is tested on home network)


if ((n2=recvfrom(sock2,qdisc_stats,sizeof(qdisc_stats),0,(struct sockaddr *) &client2, &client_len2)) < 0){
perror("Server recvfrom");
close(sock2);
}
printf("I will never print this shit \n");

I have also tried to use the gbd debugger but with no success.. Help me plz
 
Old 09-20-2005, 11:19 AM   #2
Thinking
Member
 
Registered: Oct 2003
Posts: 249

Rep: Reputation: 30
what does union qdisc look like?


what you can try is send/receive on localhost!
if this works (sending receiving on localhost) while firewall is down
you can be sure that your prog works and there is a network problem

greetz
 
Old 09-20-2005, 11:38 AM   #3
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi i have a serious serious problem.
I want to send from one pc to an other an array of unions.
It would probably be a good idea to write a small test program and verify that you can send a simple string from PC1 to PC2 on UDP port 8888, first
The variable is defined as
union qdisc qdisc_stats[10];

The packet is being send with the next system call
if (sendto( sock2, qdisc_stats, sizeof(qdisc_stats), 0, (struct sockaddr *) &server2, server_len2) <0){
perror("Client send to");
close(sock2);
}

I have selected the 8888 port for this job.
Using tcpdump i have checked that the packet is being succesfully generated and received from the other pc
Excellent
(see the last line)
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes
15:55:50.869415 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], length: 196) 192.168.1.11.9997 > 192.168.1.3.9997: UDP, length: 168
15:56:00.870447 IP (tos 0x0, ttl 64, id 24785, offset 0, flags [+], length: 1500) 192.168.1.11.8888 > 192.168.1.3.8888: UDP, length: 4800


I have also checked that the pc that waits for the packet succesfully binds to the port:

udp 0 0 192.168.1.3:137 0.0.0.0:* 6818/nmbd
udp 0 0 0.0.0.0:137 0.0.0.0:* 6818/nmbd
udp 0 0 192.168.1.3:138 0.0.0.0:* 6818/nmbd
udp 0 0 0.0.0.0:138 0.0.0.0:* 6818/nmbd
udp 0 0 0.0.0.0:161 0.0.0.0:* 6968/snmpd
udp 0 0 0.0.0.0:8888 0.0.0.0:* 27120/3threads
Good

But still the packet dont seem to be received from the programme at all
(Firewalls are closed.. Everything is tested on home network)
[COLOR=red]Unfortunately, that doesn't necessarily mean that a firewall isn't the problem

Here's my suggestion:
1. Write a simple, standalone "UDP Hello world". One program for send, one client for receive.
You can adapt your own code, or you can adapt this one:
http://www-net.cs.umass.edu/ntu_socket/

2. I would make SERVER_PORT_ID and/or SERV_HOST_ADDR command line parameters (argv[1] and argv[2])).

3. I would try running the server and client on the same machine (SERV_HOST_ADDR == 127.0.0.1) to verify
that it works, then on separate machines, to verify that it still works.

4. It really sounds to me like there probably *is* a firewall issue here. The reason I say that is:
a) you believe you verified with tcpdump (run on the server, I'm sure) that the client's packet is indeed
getting to the remote PC
... but ...
b) the server remains blocked in recvfrom()
<= SURE SOUNDS LIKE A FIREWALL PROBLEM ON THE SERVER TO ME...

5. I would vary SERVER_PORT_ID (using your cmd-line argument) and see if you find a port# that works (verifying
that your code, but the problem is in system configuration - e.g. firewall, or user privileges, or UDP max port,
or something like that).
 
Old 09-20-2005, 11:47 AM   #4
orgcandman
Member
 
Registered: May 2002
Location: new hampshire
Distribution: Fedora, RHEL
Posts: 600

Rep: Reputation: 110Reputation: 110
the best way to test is to use netcat:

IE: from server PC:
[user@server ~]$ nc -l -p 8888 -u

And from Client PC:
[user@client ~]$ nc -u server 8888

Where server is the server PC, and client is the client PC.

Once they're connected you can start typing between the two.

-Aaron
 
Old 09-20-2005, 12:10 PM   #5
alaios
Senior Member
 
Registered: Jan 2003
Location: Aachen
Distribution: Opensuse 11.2 (nice and steady)
Posts: 2,203

Original Poster
Rep: Reputation: 45
omg

I have retested using more ports but still nothing... I think this is a coding problem
Let me explain what i am trying to do.. I want to transfer two structs so i have to call the recvfrom twice

I put here all my code... I know its some kind of boring but still i have no other hope
P.s I use ubuntu that has no firewall rules.. I have checked that on forums

Servers code
Code:
void read_diff_parameters(struct diff_configuration *diff,union qdisc *qdisc){
        /*Take the parameters from the diffserv */
        printf("I am here \n");
        int sock,n,temp,sock2,n2;
        socklen_t server_len,client_len,server_len2,client_len2;
        struct sockaddr_in server,client,server2,client2;
        if ((sock=socket(PF_INET,SOCK_DGRAM,0))<0){
                  perror("Server socket");
        }
        memset(&server,0,sizeof(server));
        server.sin_family       = AF_INET;
        server.sin_addr.s_addr  = htonl(INADDR_ANY);
        server.sin_port         = htons(9997);
        if (bind(sock, (struct sockaddr *) &server, sizeof(server)) <0 ){
                        perror("Server bind ");
        }
        server_len=sizeof(server);      //Obtain address length
        if (getsockname(sock, (struct sockaddr *) &server, &server_len) <0 ){
                        perror("Server getsockname ");
        }

        client_len = sizeof(client); //Set the length
        memset(diff,0,sizeof(diff)); //clear the buffer

        if ((n=recvfrom(sock,diff,sizeof(struct diff_configuration),0,(struct sockaddr *) &client, &client_len)) < 0){
                perror("Server recvfrom ");
                close(sock);
        }
        //* I have to use the pointer ?? WARNING */
        printf("Elaba ta statistica tou diffserv \n");
        close(sock);
        for(temp=0;temp<3;temp++){
                printf("Elaba rate %d \n",diff->UseTemplate);
                printf("Elaba ceil %d \n",diff->NumberOfClasses);
        }



         if ((sock2=socket(PF_INET,SOCK_DGRAM,0))<0){
                   perror("Server socket");
         }
         memset(&server2,0,sizeof(server2));
         server2.sin_family       = AF_INET;
         server2.sin_addr.s_addr  = htonl(INADDR_ANY);
         server2.sin_port         = htons(9990);
         if (bind(sock2, (struct sockaddr *) &server2, sizeof(server2)) <0 ){
                 perror("Server bind ");
         }
         server_len2=sizeof(server2);      //Obtain address length
         if (getsockname(sock2, (struct sockaddr *) &server2, &server_len2) <0 ){
                   perror("Server getsockname ");
         }

        client_len2 = sizeof(client2); //Set the length


        if ((n2=recvfrom(sock2,qdisc_stats,sizeof(qdisc_stats),0,(struct sockaddr *) &client2, &client_len2)) < 0){
                perror("Server recvfrom");
                close(sock2);
        }
        printf("Elaba ta qdiscs mpu \n");
        logfile("---->Receiving configuration settings from DiffServ completed ",system_params.mainlogfile);
        close(sock2);

}



Client code... After sending the first struc succesfully (the second one has problems) i use the sleep so as to give the server time to bind the port. 10 secs (sleep(10)) it as huge time for this... I have checked that in netstat -ulnp output that first the server binds then the packet is generated



Code:
void send_diff(struct configuration *diff,union qdisc *qdisc){

        int                     sock,n,temp,sock2,n2;
        socklen_t               server_len,server_len2;
        struct sockaddr_in      server,client,server2,client2;
        struct hostent          *host,*host2;

        if (!(host=gethostbyname(DIFFSERV))){ //?? Huge problem how to read value from file
                perror("Client gethostname");
        }
        memset(&server,0,sizeof(server));
        server.sin_family= AF_INET;
        memcpy(&server.sin_addr,host->h_addr,host->h_length);
        server.sin_port=htons((9997));
        if ((sock=socket(PF_INET, SOCK_DGRAM, 0)) < 0){
                perror("Client socket ");
        }
        memset(&client,0,sizeof(client));
        client.sin_family       = AF_INET;
        client.sin_addr.s_addr  = htonl(INADDR_ANY);
        client.sin_port         = htons(9997);

        if ( bind(sock, (struct sockaddr *) &client, sizeof(client)) <0){
                perror("Client bind ");
        }
        server_len=sizeof(server);
        printf("To i exei timi %d \n",i);


        if (sendto( sock, diff , sizeof(struct configuration), 0,(struct sockaddr *) &server, server_len) <0){                perror("Client send to");
                close(sock);
        for(temp=0;temp<3;temp++){
                printf("Stelno rate %s \n",qdisc_stats[temp].htbstats.rate);
                printf("Stelno ceil %s \n",qdisc_stats[temp].htbstats.ceil);

        }
        close(sock);
        sleep(10);
        server2.sin_family= AF_INET;
        memcpy(&server2.sin_addr,host->h_addr,host->h_length);
        server2.sin_port=htons((9990));
        if ((sock2=socket(PF_INET, SOCK_DGRAM, 0)) < 0){
                perror("Client socket ");
        }
        memset(&client2,0,sizeof(client));
        client2.sin_family       = AF_INET;
 memcpy(&server2.sin_addr,host->h_addr,host->h_length);
        server2.sin_port=htons((9990));
        if ((sock2=socket(PF_INET, SOCK_DGRAM, 0)) < 0){
                perror("Client socket ");
        }
        memset(&client2,0,sizeof(client));
        client2.sin_family       = AF_INET;
        client2.sin_addr.s_addr  = htonl(INADDR_ANY);
        client2.sin_port         = htons(9990);

        if ( bind(sock2, (struct sockaddr *) &client2, sizeof(client2)) <0){
                perror("Client bind ");
        }
        server_len2=sizeof(server2);

        if (sendto( sock2, qdisc_stats, sizeof(qdisc_stats), 0, (struct sockaddr *) &server2, server_len2) <0){
                perror("Client send to");
                close(sock2);
        }
        printf("Finished sending structs \n");
        close(sock2);
 
Old 09-20-2005, 12:27 PM   #6
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Sorry - I've got a "Day Job" to focus on - I won't be able to help until this evening (Pacific time).

Question 1:
Are you sending and receiving, or aren't you?
Your original post suggested "No".
You absolutely need to answer this question first: you either are, or you aren't.

Question 2:
Are you passing your structs into sendto() correctly, and are you reading them recvfrom() correctly?

In either case, small standalone test programs are your friend!!! For example, look at posts #3 and #5 here:
http://www.linuxquestions.org/questi...hreadid=363900

Or experiment with the test programs here:
http://www-net.cs.umass.edu/ntu_socket/
 
Old 09-20-2005, 12:54 PM   #7
alaios
Senior Member
 
Registered: Jan 2003
Location: Aachen
Distribution: Opensuse 11.2 (nice and steady)
Posts: 2,203

Original Poster
Rep: Reputation: 45
generally i can send and receive... the problem is only on one specific struct that cant be received!! !dont know why...
Is it clear now?
The problem is only on the second struct... What i have explained so long is only for the second struct...
 
Old 09-20-2005, 04:33 PM   #8
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
How's the test app coming?

Hi -

Hopefully you've taken my advice about writing a standalone test program to focus on the problem. Maybe you've even resolved it.

If not, however, please e-mail me your data definitions (for "struct diff_configuration", "union qdisc", and whatever other data types you're trying to pass between the PCs), and I'll write a quick'n'dirty test program for you.

Or - better yet - I'd be happy to work with you on the standalone test that *you've* written ;-)

Your .. PSM
 
Old 09-20-2005, 09:34 PM   #9
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hello???

Have you resolved the problem?

Did you write the standalone tests?

If not, did you e-mail the struct declarations in question so that *I* could write the test and we could resolve this together?
 
Old 09-21-2005, 02:07 AM   #10
JCipriani
Member
 
Registered: Aug 2005
Location: Pittsburgh, PA, USA
Distribution: Redhat 9, OS X 10.4.x, Win2K
Posts: 85

Rep: Reputation: 15
One problem that sticks out immediately to me just glancing at your code is that you are making the mistake of assuming that sendto() and recvfrom() are sending and receiving, respectively, either all of the data you ask them to send/receive, or none of the data at all.

Consider this:
Code:
if (recvfrom(...) < 0)
  printf("data wasn't received");
else
  printf("all data was received");
Well, if you are trying to receive 100 bytes of data but you only get 5 bytes (or no bytes at all), that snippet still thinks that all data was received when in fact it wasn't. This happens regardless of whether or not the socket is non-blocking.

You should check the actual return values of your sendto() and recvfrom() calls and verify that you are, in fact, sending and receiving the number of bytes you think you are. It's entirely possible that the kernel is just deciding that it doesn't want to send or receive everything you want all at once, but your program isn't set up to handle that possibility (which is a likely possibility).

So.... what are your sendto() and recvfrom() calls returning? And what are the sizes of those structures that you are sending and receiving?

On another note, it's generally a bad idea to send or receive entire structures worth of data directly from and to memory unless you can safely make assumptions about the alignment of the data in those structures. For example, on my machine, the following program:

Code:
#include <stdio.h>

struct s {
  char a;
  long b;
  char c;
};

int main (void) {
  printf("sizeof(s) = %i\n", sizeof(struct s));
  return 0;
}
Outputs 12 as the size. If your client is sending data to a server and the server just happened to be compiled with a compiler that used a different structure alignment then you're going to run into a lot of problems. It's best to send the data one member at a time and receive it that way as well. That's unrelated to your original problem but it's still something I noticed.
 
Old 09-21-2005, 02:16 AM   #11
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi, JCipriani.

You make an extremely good point. Furthmore, my guess is that alaios is probably using UDP datagrams, which makes the scenario you suggested even more likely.

But I believe that the problem could just as easily be syntax errors dealing with 'C' structures. Or something else entirely. I believe that alaios will save himself an awful lot of frustration and grief by focusing on one small aspect of the problem at a time.

IMHO .. PSM
 
Old 09-21-2005, 10:30 AM   #12
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
JCipriani, with UDP packets, packet boundaries are preserved. Meaning that if you send 100 bytes, you can be sure that if you receive it on the other end, you will receive 100 bytes. It's one of the advantages over TCP sockets where you have to manage the packet boundaries yourself. So, this isn't likely the problem.

The struct alignment would be a good thing to test, though. If your struct members don't fall on the default alignment for your compiler they will be padded. An easy way to avoid this is to specify a packing alignment of 1. For instance, whenever I want to use a struct to read/write directly to a file or as a network packet, I do something like so:

Code:
// Push the current packing alignment (usually 8 for most compilers I've worked 
// with) to a stack and then set it to 1
#pragma pack(push, 1)
struct s {
  char a;
  long b;
  char c;
};
// Return the packing alignment to whatever it was previously
#pragma pack(pop)

I took a quick look at the code posted in post #5 and didn't see much, but the definitions of the structs being sent/received don't seem to be there and would seem to be important information.
 
Old 09-21-2005, 10:39 AM   #13
JCipriani
Member
 
Registered: Aug 2005
Location: Pittsburgh, PA, USA
Distribution: Redhat 9, OS X 10.4.x, Win2K
Posts: 85

Rep: Reputation: 15
Quote:
JCipriani, with UDP packets, packet boundaries are preserved. Meaning that if you send 100 bytes, you can be sure that if you receive it on the other end, you will receive 100 bytes. It's one of the advantages over TCP sockets where you have to manage the packet boundaries yourself. So, this isn't likely the problem.
Oh... well, there goes that theory. The code only checks to see if the return values are less than 0, though... maybe they are returning 0? If nothing is sent at all but there was no error (rather than a partial packet) the original program would still think everything was sent. But I don't know if that happens when the sockets are blocking.

Last edited by JCipriani; 09-21-2005 at 10:41 AM.
 
Old 09-21-2005, 10:55 AM   #14
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32
Yeah, checking the value returned by recvfrom would be a good idea. With TCP sockets, the only time recv should return a 0 is if the other side closed the connection. Since UDP is connectionless, recvfrom should always have a size greater than 0 unless there is some other sort of error. With blocking sockets, recv and recvfrom will sit there until there is an error, or something is received. In a final server, it's almost always a good idea to see if the recv/recvfrom will block by using select first.
 
Old 09-21-2005, 11:05 AM   #15
orgcandman
Member
 
Registered: May 2002
Location: new hampshire
Distribution: Fedora, RHEL
Posts: 600

Rep: Reputation: 110Reputation: 110
A view of what the actual structures are might be good.

Also, make sure to pack your structs using

__attribute__((packed))

ex:

Code:
	struct test
	{
    	    unsigned char  field1;
    	    unsigned short field2;
    	    unsigned long  field3;
	} __attribute__((__packed__));
Also, in your provided examples, why is it that you're closing the socket and then immediately opening a new one? Just use the one you already have (unless there's some sort of standards you're trying to implement).

Also, you don't need to bind for the client side. You just call sendto()s. If you're using UDP though, you might want to have ACK messages for your system.
 
  


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
My email server sends mails but does not receive hubergeek Linux - Networking 2 07-14-2010 08:27 AM
FC3 and new QMail install - sends ok, can't receive ericcarlson Fedora 2 02-27-2005 03:02 PM
Evolution sends but does not receive? SheldonPlankton Linux - Software 3 02-11-2005 04:12 AM
qmail sends but doesn't receive mail ysg08 Linux - Networking 5 01-14-2005 03:01 PM
Sendmail sends but doesn't receive r-l-j Linux - General 0 11-13-2002 12:45 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:24 PM.

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
Open Source Consulting | Domain Registration