LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
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 08-04-2008, 08:31 AM   #1
shifter
Member
 
Registered: May 2006
Distribution: Slackware, DragonFly
Posts: 233

Rep: Reputation: 30
problem with sending messages in socket programs


I have a big problem with sockets.
My two programs are:

- server.c (TCP server)
- client..c (TCP client)

I type in first shell:

#./server 3000 (./server <port number>)

and after I type:

#./client CC1 3000 (./client <hostname> <port number>)

I send a message from client to server, but server don't receive above message.
 
Old 08-04-2008, 09:43 AM   #2
vladmihaisima
Member
 
Registered: Oct 2002
Location: Delft, Netherlands
Distribution: Gentoo
Posts: 196

Rep: Reputation: 33
Without some code, nobody will be able to help you.
 
Old 08-04-2008, 09:49 AM   #3
shifter
Member
 
Registered: May 2006
Distribution: Slackware, DragonFly
Posts: 233

Original Poster
Rep: Reputation: 30
I am doing some test.
The client.c program send byte, but the error is in server.c. The server don't receive byte. recv return -1, the error is:

Error code = 88: Socket operation on non-socket

Last edited by shifter; 08-04-2008 at 10:16 AM.
 
Old 08-04-2008, 10:32 AM   #4
shifter
Member
 
Registered: May 2006
Distribution: Slackware, DragonFly
Posts: 233

Original Poster
Rep: Reputation: 30
My code is the following:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char*argv[])
{

int connectFd, listenFd, portn, clientlen, nbyte, i;
char buffer[256];
struct sockaddr_in addrserv, addrclient;
int cltlen;


if (argc < 2) printf("Devi inserire il numero di porta");
listenFd = socket(AF_INET, SOCK_STREAM, 0);
printf("listenFd = %d ", listenFd);
if (listenFd < 0)
perror("Errore nella apertura del socket");
bzero(&addrserv, sizeof(addrserv));
portn = atoi(argv[1]);
addrserv.sin_family = AF_INET;
addrserv.sin_addr.s_addr = htonl(INADDR_ANY);
addrserv.sin_port = htons(portn);
if (bind(listenFd, (struct sockaddr*)&addrserv, sizeof(addrserv)) < 0)
perror("Errore nella operazione di bind del socket");
if (listen(listenFd, 5) < 0)
perror("Errore nella operazione di listen del socket");
cltlen = sizeof(addrclient);

if (connectFd = accept(listenFd, (struct sockaddr*)&addrclient, (socklen_t*)&cltlen) <= 0) {
printf("ConnectFd = %d ", connectFd);
perror("Errore nella operazione di accept ");
}
printf("ConnectFd = %d ", connectFd);
bzero(buffer, 256);
if (nbyte = recv(connectFd, buffer, 255, 0) < 0) {
printf("Codice errore: %d", errno);
perror("Errore nella ricezione");
}
printf("Byte ricevuti: %d", nbyte);

shutdown(connectFd, SHUT_RDWR);
close(connectFd);
return 0;

}

In my opinion the problem is in accept function. Accept() return 0 as socket descriptor, but I think that is not valid!
 
Old 08-04-2008, 12:58 PM   #5
vladmihaisima
Member
 
Registered: Oct 2002
Location: Delft, Netherlands
Distribution: Gentoo
Posts: 196

Rep: Reputation: 33
From man page of accept:
Quote:
On success, accept() returns a non-negative integer that is a descriptor for the accepted socket. On error, -1 is returned, and errno is set appropriately.
0 seems a good value. You should change the test to:

Code:
if (connectFd = accept(listenFd, (struct sockaddr*)&addrclient, (socklen_t*)&cltlen) < 0) {
And please, when you put code, use the code tag. (it is in the editor...)
 
Old 08-04-2008, 09:46 PM   #6
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Another problem is that you need to handle errors a bit better. In this example, I simply terminate the program with a "perror()" and a "return 1" if anything goes wrong.

Also note the "code tags" vladmihaisima mentioned:
Code:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

int main(int argc, char*argv[])
{

  int connectFd, listenFd, portn, clientlen, nbyte, total_bytes, i;
  char buffer[256];
  struct sockaddr_in addrserv, addrclient;
  int cltlen;

  if (argc < 2) 
  {
    printf("Devi inserire il numero di porta");
    return 1;
  }

  listenFd = socket(AF_INET, SOCK_STREAM, 0);
  if (listenFd < 0)
  {
    perror("Errore nella apertura del socket");
    return 1;
  }
  printf("listenFd = %d ", listenFd);

  bzero(&addrserv, sizeof(addrserv));
  portn = atoi(argv[1]);
  addrserv.sin_family = AF_INET;
  addrserv.sin_addr.s_addr = htonl(INADDR_ANY);
  addrserv.sin_port = htons(portn);
  if (bind(listenFd, (struct sockaddr*)&addrserv, sizeof(addrserv)) < 0)
  {
    perror("Errore nella operazione di bind del socket");
    return 1;
  }

  if (listen(listenFd, 5) < 0)
  {
    perror("Errore nella operazione di listen del socket");
    return 1;
  }

  cltlen = sizeof(addrclient);
  if (connectFd = accept(listenFd, (struct sockaddr*)&addrclient, (socklen_t*)&cltlen) < 0) 
  {
    perror("Errore nella operazione di accept ");
    return 1;
  }
  printf("ConnectFd = %d ", connectFd);

  bzero(buffer, 256);
  if (nbyte = recv(connectFd, buffer, 255, 0) < 0)
  {
     printf("Codice errore: %d", errno);
     perror("Errore nella ricezione");
  }
  printf("Byte ricevuti: %d", nbyte);

  shutdown(connectFd, SHUT_RDWR);
  close(connectFd);
  close(listenFd);
  printf ("Ciao!\n");
  return 0;
}
Also - are you sure the client actually *sends* a byte?

Please be sure to put the same kind of error checking into your client as we did above, in your server.

Also: consider a tool like Wireshark (formerly "Ethereal") to study the bytes being sent and received over the specified port:

http://www.wireshark.org/

'Hope that helps .. PSM

Last edited by paulsm4; 08-04-2008 at 09:51 PM.
 
Old 08-05-2008, 06:13 AM   #7
shifter
Member
 
Registered: May 2006
Distribution: Slackware, DragonFly
Posts: 233

Original Poster
Rep: Reputation: 30
The program don't work.
About ethereal or wireshark use, I am trying my client and server on local host.

My client is the following:

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

int main(int argc, char* argv[]) {

int sockfd, nbyte;
struct sockaddr_in srv_addr;
char buffer[256];

if (argc != 3) {
printf("Command syntax \n");
printf(" server <IP ADDRESS> <PORT NUMBER> \n");
}
else {
if (sockfd = socket(AF_INET, SOCK_STREAM, 0) < 0) {
printf("Error code: %d\n", errno);
perror("Error in socket()");
}
srv_addr.sin_family = AF_INET;
srv_addr.sin_port = htons(argv[2]);
srv_addr.sin_addr.s_addr = inet_addr(argv[1]);

if (connect(sockfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr)) < 0) {
printf("Error code: %d\n", errno);
perror("Error in connect()");
}
printf("Inserrt message to send");
bzero(buffer, 256);
fgets(buffer, 255, stdin);

if (nbyte = send(sockfd, buffer, strlen(buffer), 0) < 0) {
printf("Error code: %d\n", errno);
perror("Error in send()");
}
printf("Sent bytes: %d ", nbyte);
if (nbyte < 0)
perror("Errore nella scrittura su socket");
bzero(buffer, 255);

}
shutdown(sockfd, SHUT_RDWR);
close(sockfd);
return 0;

}

My server program is the following:

#include <stdio.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>


int main(int argc, char* argv[]) {

int sockfd, new_fd;
struct sockaddr_in srv_addr, clt_addr;
int clt_size, nbyte;
char buffer[256];

if (argc != 2) {
printf("Command syntax \n");
printf(" server <PORT NUMBER> \n");
}
else {
if (sockfd = socket(AF_INET, SOCK_STREAM, 0) < 0)
perror("Error in socket()");
clt_addr.sin_family = AF_INET;
clt_addr.sin_port = htons(argv[1]);
clt_addr.sin_addr.s_addr = htonl(INADDR_ANY);
memset(srv_addr.sin_zero, '\0', sizeof(srv_addr.sin_zero));

if (bind(sockfd, (struct sockaddr*)&clt_addr, sizeof(srv_addr)) < 0) {
printf("Error code: %d\n", errno);
perror("Error in bind()");
}
if (listen(sockfd, 5) < 0) {
printf("Error code: %d\n", errno);
perror("Error in listen()");
}
clt_size = sizeof(clt_addr);
if (new_fd = accept(sockfd, (struct sockaddr*)&clt_addr, &clt_size) < 0) {
printf("Error code: %d\n", errno);
perror("Error in accept()");
}
bzero(buffer, 256);
if (nbyte = recv(new_fd, buffer, 255, 0) < 0) {
printf("Error code: %d\n", errno);
perror("Error in recv()");
}
printf("Received bytes: %d", nbyte);

shutdown(new_fd, SHUT_RDWR);
close(new_fd);
return 0;

}

}

The test is:

#./server 5500
Error code: 88
Error in bind(): Socket operation on non-socket
Error code: 88
Error in listen(): Socket operation on non-socket
Error code: 88
Error in accept(): Socket operation on non-socket
Error code: 88
Error in recv(): Socket operation on non-socket
#

...

#./client CC1 6000
Error code: 88
Error in connect(): Socket operation on non-socket
Inserrt message to send

I am desperated...
 
Old 08-05-2008, 09:12 AM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Without having read your client code (I might have, if you'd taken the advice of at least two others, and posted it in [CODE] tags), I always advocate for using a known good client or server for the peer node when developing networking applications. As a client, telnet is usually a good choice. As a server, I favor netcat (nc). Doing this allows you to focus your efforts on only one end of the system, getting it working without having to consider which side of the system is causing a failure. Sometimes, a very simple client or server implementation in a scripting language such as Perl can be an asset, due to the easy parsing or disassembly of received data, and fast turnaround of modifications.
--- rod.
 
Old 08-05-2008, 10:48 AM   #9
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
I think the problem is in tests like:
Code:
if (sockfd = socket(AF_INET, SOCK_STREAM, 0) < 0) {
= has a lower precedence than <, so if the socket call succeeds, sockfd gets the result of the comparison which is 1 (true). You should write it like this:

Code:
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
or even

Code:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
If you compile with -Wall gcc will tell about this ("suggest parentheses around assignment used as truth value").

Also
Code:
srv_addr.sin_port = htons(argv[2]);
should be
Code:
srv_addr.sin_port = htons(atoi(argv[2]));
(same fix needed in client, of course)
 
Old 08-05-2008, 04:11 PM   #10
skoona
Member
 
Registered: Mar 2004
Location: Indiana, USA
Distribution: Fedora, CentOS, Ubuntu, OS/X, Raspbian
Posts: 90

Rep: Reputation: 18
shifter,

the following code sections contain you original source with some markup from me. Most of the markup is in the server.c file. The code compiles, and works as designed. Although you know you should make several improvements in error checking and flow control. Let me know what more you need. Again, here is a link with more detailed examples and discussion. http://www.beej.us/guide/bgnet/outpu...l#simpleserver

Code:
/* client.c 
 *  gcc -Wall -o client client.c
 *  usage: ./client 127.0.0.1 6000
*/
#include <stdio.h>
#include <stdlib.h>             /* for atoi()     */
#include <unistd.h>             /* for close()    */
#include <string.h>             /* for strerror(), bzero() */
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

int main(int argc, char* argv[]) 
{

  int sockfd, nbyte;
  struct sockaddr_in srv_addr;
  char buffer[256];

  if (argc != 3) {
    printf("Command syntax \n");
    printf(" server <IP ADDRESS> <PORT NUMBER> \n");
  }
  else {
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
      perror("Error in socket()");
    }
    srv_addr.sin_family = AF_INET;
    srv_addr.sin_port = htons(atoi(argv[2]));
    srv_addr.sin_addr.s_addr = inet_addr(argv[1]);

    if (connect(sockfd, (struct sockaddr*)&srv_addr, sizeof(srv_addr)) < 0) {
      perror("Error in connect()");
      return 1;
    }
    printf("Inserrt message to send");
    bzero(buffer, 256);
    fgets(buffer, 255, stdin);

    if ((nbyte = send(sockfd, buffer, strlen(buffer), 0)) < 0) {
        perror("Error in send()");
    }
    printf("Sent bytes: %d ", nbyte);
    if (nbyte < 0)
      perror("Errore nella scrittura su socket");
    
    bzero(buffer, 255);
    shutdown(sockfd, SHUT_RDWR);
    close(sockfd);
    return 0;
  }

  return 1;
}
Code:
/* server.c 
 *  gcc -Wall -o server server.c
 *  usage: ./server 6000 
*/

#include <stdio.h>
#include <stdlib.h>             /* for atoi()     */
#include <unistd.h>             /* for close()    */
#include <string.h>             /* for strerror() */
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

int main(int argc, char* argv[]) 
{

  int sockfd, new_fd;
  struct sockaddr_in srv_addr, clt_addr;
  int clt_size, nbyte;
  char buffer[256];

  if (argc != 2) {
    printf("Command syntax \n");
    printf(" server <PORT NUMBER> \n");
  }
  else {
    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
      printf("Error in socket() %d, %s", errno, strerror(errno));   /* added some extra info */
      return 1;                                                      /* no need to continue */
    }
    
    clt_addr.sin_family = AF_INET;
/*    clt_addr.sin_port = htons(argv[1]);          needs to be an int, argv[1] is a string now] */
    clt_addr.sin_port = htons(atoi(argv[1]));  
/*    clt_addr.sin_addr.s_addr = htonl(INADDR_ANY);        INADDR_ANY is already in the right format */ 
    clt_addr.sin_addr.s_addr = INADDR_ANY;
    memset(srv_addr.sin_zero, '\0', sizeof(srv_addr.sin_zero));

    if (bind(sockfd, (struct sockaddr*)&clt_addr, sizeof(srv_addr)) < 0) {
        printf("Error in bind(): %d, %s", errno, strerror(errno));
        close (sockfd);
        return 1;
    }
    if (listen(sockfd, 5) < 0) {
        printf("Error in listen(): %d, %s", errno, strerror(errno));
        close (sockfd);
        return 1;
    }
    clt_size = sizeof(clt_addr);
    if ( (new_fd = accept(sockfd, (struct sockaddr*)&clt_addr, (socklen_t *)&clt_size)) < 0) {        /* cast to (socklen_t *)&clt_size   */
      printf("Error in accept(): %d, %s", errno, strerror(errno));
      close (sockfd);
      return 1;
    }
    bzero(buffer, 256);
    if ( (nbyte = recv(new_fd, buffer, 255, 0)) < 0) {                          /* more () to clean up compile warning */
      printf("Error in recv(): %d, %s", errno, strerror(errno));
      close (new_fd);    
      close (sockfd);      
      return 1;
    }
    printf("Received bytes: %d", nbyte);

    shutdown(new_fd, SHUT_RDWR);
    close(new_fd);
    return 0;
  }

  return 1;
}
 
Old 08-06-2008, 06:58 AM   #11
shifter
Member
 
Registered: May 2006
Distribution: Slackware, DragonFly
Posts: 233

Original Poster
Rep: Reputation: 30
I solved above problem. I posted an other question for my current question

Thanks everyone answered.
 
  


Reply



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
Sending Messages in Console? carlosinfl Linux - General 3 03-21-2008 07:13 PM
Qmail delivery problem - messages temporarily_deferred sending to yahoo or hotmail karen.pertierra Linux - General 1 02-12-2007 12:53 PM
Sending messages tired Linux - Newbie 2 08-11-2004 02:37 AM
Sending messages over SSH jeucken Linux - Networking 1 12-15-2003 01:54 PM
Sending messages across a network... kierl Linux - General 3 04-07-2003 01:11 PM

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

All times are GMT -5. The time now is 12:27 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