Link to home
Start Free TrialLog in
Avatar of cmaryus
cmaryus

asked on

EPIPE in send(), Berkley sockets

I have a client application that runs on Linux RH, and a server the runs on WinXP.From the client application I connect to the server, then i try to send some data, and I receive an EPIPE error. In documentation it says that this error ocurs when the peer socket is closed, but in the server I don't close the client socket.
Funny is that, i have a version of the client on WinXP, which works fine.
Any ideea?

Thanks,
marius
Avatar of skian
skian

Have you checked whether the connect() call succeeded ?
Do you use a async connect() ?

You said that when both the client & server are on
winxp the client works fine. Are the client and the
server running on different hosts ?

Stephane
[EPIPE]   The socket is shut down for writing, or the socket is
            connection-oriented and the peer is closed or shut down for read-
            ing. In the latter case, and if the socket is of type
            SOCK_STREAM, the SIGPIPE signal is generated to the calling pro-
            cess.

SIGPIPE signal maybe? Signal interrupt any blocking operations in blocking socket.
Avatar of cmaryus

ASKER

I just don't get it...i've made 2 very small test projects: client and server. I've tested in this way:
- start client
- client trying to conect...in keeps receiving ECONREFUSED
- start server
- in this moment client is connected
- on the server side i try to receive data from client
- when i try to send data from client I receive EPIPE (of course this comes with SIGPIPE, which I ignore)

If I do in this way:
- start server first
- start client
- client is connected ok
- client send ok !!!

So when i start the server first ...everything is ok !!!!
When i start the client first...EPIPE...

On Win XP the it works, no matter if i start the client or server first...
could you post the relevant source code part ?
Avatar of cmaryus

ASKER

This is a small test i've made...

Client:
client.cpp

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

int main(int argc, char* argv[])
{
     signal(SIGPIPE, SIG_IGN);
     
    int sock = socket(AF_INET, SOCK_STREAM, 0);
   
   
    while(true)
    {
   
     sockaddr_in sockAddr;
     memset(&sockAddr,0,sizeof(sockAddr));

     sockAddr.sin_family = AF_INET;
     sockAddr.sin_addr.s_addr = inet_addr(argv[1]);
     sockAddr.sin_port = htons((u_short)(atoi(argv[2])));
   
     
     int x = connect(sock, (struct sockaddr*)&sockAddr, sizeof(sockAddr));
     if (x == 0)
     {
         break;
     }
     else
     {
         cout << "Connect err: " << strerror(errno) << endl;    
     }
     usleep(1000000);
    }

    cout << "connect ok" << endl;
   
    char szMsg[100];
    strcpy(szMsg, "test");
    while(true)
    {
     int x = send(sock, szMsg, strlen(szMsg), 0);
        if (x == -1)
     {
          cout << "send err " << strerror(errno) << endl;
     }
        else
     {
          cout << "send OK" << endl;
     }
     usleep(1000000);
    }
   
    shutdown(sock, 2);
}


Server:
server.cpp

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

int main(int argc, char* argv[])
{
    signal(SIGPIPE, SIG_IGN);
     
    int sock = socket(AF_INET, SOCK_STREAM, 0);
   
    sockaddr_in sockAddr;
    memset(&sockAddr,0,sizeof(sockAddr));

    sockAddr.sin_family = AF_INET;
    sockAddr.sin_addr.s_addr = inet_addr(argv[1]);
    sockAddr.sin_port = htons((u_short)(atoi(argv[2])));
   
    int x = bind(sock, (struct sockaddr*)&sockAddr, sizeof(sockAddr));
    if (x == 0)
     {
         printf("\nbind ok");;
     }
     else
     {
         perror("\n bind ");    
     }

    listen(sock, 5);
   
    int xxx;
   
    while(true)
    {
   
     xxx = accept(sock, NULL, NULL);
     if (xxx == -1)
     {
         perror("\n accept ");    
     }
     else
     {
         printf("\n accept ok");
         break;
     }
     usleep(100000);
    }


     fcntl(xxx, F_SETFL, O_NONBLOCK);

     char msg[100];
     int zzzz = recv(xxx, msg, 10, 0);

    shutdown(sock, 2);
}


You start the processes like this:
client 10.11.12.13 1111
server 10.11.12.13 1111
(first param ip, second port)
If i start the client first-> send fails
If i start the server first, then client , the send is ok !

Please help...I'm desperate...i'm working on this since thursday...
Avatar of cmaryus

ASKER

Until now I made the test on a RH6.2. When I make the tests on RH8.0...it works....could this be the problem?
ASKER CERTIFIED SOLUTION
Avatar of skian
skian

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of cmaryus

ASKER

I know what fcntl does, i tested without it and still the same.
so print zzzz value
Avatar of cmaryus

ASKER

when in the blocking mode, recv don't return at all. in send i receive EPIPE...
Avatar of cmaryus

ASKER

  Thanks guys but I've succeeded to solve this problem: in the client code, after each unsuccessfull connect i close and create the socket again.
   So I hope it's ok to get my points back...
Avatar of Kyle Abrahams, PMP
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept Skians answer.  He helped to lead cmaryus to the solution.

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Ged
EE Cleanup Volunteer