0

I have a client side source code that connects to server over internet.
When I tracing my code it shows me the SIGPIPE error when the compiler run send code. where is my problem?
I changed send method as the comment say and used strcpy.
But I have error again.

#include <QCoreApplication>
#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
#include <string>    /*To use string type*/
#include <iostream>
#include <string>
#include <QChar>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <typeinfo>//for print the type typeid(a).name --> int
#include <string>
#include <arpa/inet.h>
#include <signal.h>
//#include <pthread.h> //make thread
using namespace std ;

//________________
#define bufsize 100
int sock;
struct sockaddr_in server;
string str;
char*     message = new char[bufsize];
char*     server_reply = new char[bufsize];
void RECV()
{
        memset(&server_reply,'\0',bufsize);
        int a=recv(sock , server_reply ,bufsize  , 0);
        cout<<a;
        if(server_reply[0]!='\0')
        cout<<server_reply<<endl;

}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    sock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);//0
    if (sock == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");
    server.sin_addr.s_addr = inet_addr("example.com");//
    server.sin_family = AF_UNSPEC;//AF_INET;
    server.sin_port = htons( 3490 );


    //Connect to remote server
    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        perror("connect failed. Error");
        return 1;
    }

    puts("Connected\n");
    puts("Bienvenido al Chatroom, puedes empezar a escribir en la sala!");

    strcpy(message,"Hi");
    signal(SIGPIPE, SIG_IGN);
    if((send(sock , message , strlen(message)+1 , 0))<0)
    {
        perror("send");
        exit(1);
    }
    RECV();   
    close(sock);
    return a.exec();
}
H.Ghassami
  • 1,012
  • 2
  • 21
  • 42

1 Answers1

0

In both memset calls, you are passing the address of the pointer rather than the pointer itself. Because bufsize is 100, these memset calls will corrupt other memory. At that point, any number of bad things can happen.

Below is my version of your code that does not get the SIGPIPE. Most notable is that AF_UNSPEC has been changed to AF_INET.

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>

#define bufsize 100

static int sock;
static char* message      = new char[bufsize];
static char* server_reply = new char[bufsize];

static void RECV(int sock)
{
  recv(sock, server_reply, bufsize, 0);

  printf("%s\n", server_reply);
}

int main(int argc, char *argv[])
{
  struct sockaddr_in server;

  message      = new char[bufsize];
  server_reply = new char[bufsize];

  sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (sock == -1)
  {
    printf("Could not create socket");
    return 1;
  }

  puts("Socket created");
  server.sin_addr.s_addr = inet_addr("93.184.216.34");
  server.sin_family = AF_INET;
  server.sin_port = htons( 80 );

  if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
  {
    perror("connect failed. Error");
    return 1;
  }

  puts("Connected\n");
  puts("Bienvenido al Chatroom, puedes empezar a escribir en la sala!");

  strcpy(message,"GET http://example.com/index.html HTTP/1.1\r\n\r\n");
  signal(SIGPIPE, SIG_IGN);

  if ((send(sock, message, strlen(message)+1, 0))<0)
  {
    perror("send");
    return 1;
  }

  puts("Sent\n");
  RECV(sock);
  close(sock);
  return 0;
}
MarkGlenn
  • 28
  • 1
  • 4
  • thanks for reply. I changed the code from memset to " for(int i=0;i<100;i++) message[i]='\0';" but I have the same error – H.Ghassami Jan 09 '16 at 07:34
  • Why write a loop? Just remove the `&` from the `memset` call. That is what the answer given is basically stating. You're calling `memset` incorrectly. – PaulMcKenzie Jan 09 '16 at 07:37
  • I removed & but again error. :( – H.Ghassami Jan 09 '16 at 07:43
  • You don't need `memset()` at all, but this doesn't answer the question. It should have been posted as a comment. – user207421 Jan 09 '16 at 07:46
  • I removed memset. but I have error again. In (http://stackoverflow.com/questions/4584904/what-causes-the-broken-pipe-error) they clode socket. but in my code and server we dont use close( socket) – H.Ghassami Jan 09 '16 at 07:56
  • The third argument to the `socket` call should be `IPPROTO_TCP`. @EJP is right, of course -- I should have posted a comment instead of an answer. – MarkGlenn Jan 09 '16 at 15:37
  • @H.Ghassami - There are problems with your `send` call and its setup: 1. Change `message="Hi"+'\0';` to `strcpy(message, "Hi");`. 2. Change `send(sock, message, sizeof(message), 0);` to `send(sock, message, strlen(message)+1, 0);`. – MarkGlenn Jan 09 '16 at 18:27
  • @MarkGlenn thanks . I changed the code and use strcpy and send(sock , message , strlen(message)+1 , 0) but when compiler receive the send line again show me BrokenPipe error – H.Ghassami Jan 10 '16 at 05:17
  • @H.Ghassami - Did you also change the third argument of the `socket` call to `IPPROTO_TCP`? (See comment above.) – MarkGlenn Jan 10 '16 at 05:22
  • thanks.Yes I changed sock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);//0. but again show me the broken pipe error. ( really thanks for reply) – H.Ghassami Jan 10 '16 at 06:53
  • @H.Ghassami - A few things: 1) In your edited code, I don't see the `IPPROTO_TCP` in the socket. 2) Your `send` should read: `if (send(...) < 0)`. 3) Are you absolutely certain that the `SIGPIPE` occurs on the `send`? Place a `puts` after the `send` to be sure. 4) Port `216` is reserved for a license server. Is this what you are connecting to? Very likely sending `Hi` to a license server will cause it to close your connection. 5) Consider ignoring the `SIGPIPE` -- `signal(SIGPIPE, SIG_IGN);` -- and handle the error inline. 6) The third argument to `recv` should be `bufsize`, not `20`. – MarkGlenn Jan 10 '16 at 16:04
  • @H.Ghassami - I take back #6. In a blocking `recv`, you should specify the number of bytes that you expect your peer to send you. – MarkGlenn Jan 12 '16 at 01:38
  • @MarkGlenn: really thanks thank to reply.to answer your Qs:1) I forgot to edit code. I just test it in my code .2)I changed that.3)yes. After I changed these, Again after compiler come on send line the brokenpipe error occured.4)I changed the port to 3490,5)I put your code.6) changed 20 to bufsize ( realy realy thanks again) I shamed. but i dont know why broken pipe occured again(edit source code) – H.Ghassami Jan 12 '16 at 06:31
  • @H.Ghassami - I recreated the problem. To get past the `SIGPIPE`, change `AF_UNSPEC` to `AF_INET`. Other things that you must change: 1) Change `example.com` to `93.184.216.34` because `inet_addr` only accepts an IP address. 2) Change port `3490` to `80` because you are connecting to an `HTTP` service. 3) You should remove the `memset` because it is unnecessary and will cause corruption the way it is coded (see previous comments). 4) Change `"Hi"` to `"GET http://example.com/index.html HTTP/1.1\r\n\r\n"` so that the server will send you something to `recv`. – MarkGlenn Jan 12 '16 at 15:40
  • @MarlGlenn: really thanks to helping me. I changed my server from internet to localhost and also changed #4 and #1(from your comment) ,then problem solved. after that I get that my Ubuntu on VMware dose not access to internet( over bridge network) and I think cause of this I got that error from send method. although , really thanks to help me. thanks – H.Ghassami Jan 13 '16 at 10:57