Computing > Networking & Wireless

C networking, not working on 127.0.0.1

(1/3) > >>

legacy:
so I have these two examples, a simple server and a simple client (config.h, Makefile); They work perfectly on a Linux MachineA, but they do not work on a MachineB.

MachineA(ip=192.168.1.81):

--- Code: ---./server &
./client 127.0.0.1
Sun Mar  3 17:32:18 2019
./client 192.168.1.81
Sun Mar  3 17:32:46 2019

--- End code ---

MachineB(ip=192.168.1.24):

--- Code: ---./server &
./client 127.0.0.1

^C
./client 192.168.1.24

^C

--- End code ---
the client was blocked, so I terminated the client by pressing CTRL + C


MachineB, connecting to MachineA

--- Code: ---./client 192.168.1.81
Sun Mar  3 17:32:46 2019

--- End code ---


so ... I am a bit perplexed  :-//

mrflibble:
Presumably because you try to listen on a privileged port?  :-//

I notice that in config.h the port number is defined as 501. Certain problems might just go away when you change that to the carefully crafted port number of 10501.

Chances are pretty good that the bind() call in server.c returns -1. Since there is currently no check on this return value, this error is silently ignored, possibly causing some head scratching moments. :)

man bind:
RETURN VALUE
       On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.

Checking of return values is left as an exercise for the reader. ;)

ejeffrey:
A quick way to check this is 'netstat -l' will show you all listening sockets.  If something has bound to the socket you should be able to see it 'netstat -np' will show you the PID holding the socket.

Another possibility is that machine B already has a process bound to the port you are trying to use, or machine B has messed up firewall rules.  Checking of return values is always a good place to start diagnosing problems.

In particular, I expect that if the problem is failing to bind to a privileged port, the client should fail with a connection refused -- unless the firewall is also set up to block connection refused even on localhost.  On the other hand, if there is another server on that port that doesn't do what you expect then you could see the stall you describe.

Note: both of your links are to the server code.

MarkF:
I wrote a TCP Socket C++ socket class years ago for a SGI, REDHAT and Windows machines.
I removed the SGI code.  So, hopefully I didn't mess anything up.
REDHAT should work for a Linux machine.

tcpSocket.h:

--- Code: ---#ifndef __TCPSOCKET_H
#define __TCPSOCKET_H

#ifdef REDHAT
   #define INVALID_SOCKET -1
   #include <stdio.h>
   #include <unistd.h>
   #include <fcntl.h>
   #include <strings.h>
   #include <sys/types.h>
   #include <sys/ipc.h>
   #include <sys/shm.h>
   #include <sys/socket.h>
   #include <netinet/in.h>
   #include <netinet/tcp.h>
   #include <arpa/inet.h>

   #if   !defined(TRUE) || ((TRUE) != 1)
   #define  TRUE  (1)
   #endif
   #if   !defined(FALSE) || ((FALSE) != 0)
   #define  FALSE (0)
   #endif
#endif

#ifdef WIN32
   #include <stdio.h>
   #include <winsock2.h>
#endif

class tcpSocket {

public:
   tcpSocket();
   ~tcpSocket();

   int openClient(unsigned short port, char *addr);
   int openServer(unsigned short port, char *addr);
   void checkSocket(void);
   void closeSocket(void);

   // WRITE MESSAGE
   //    Return:  -1=Error writing message, >0=Number bytes written
   int writeMsg(char *msg, int size);

   // READ MESSAGE
   //    Return:  -1=Error reading message, 0=No message, >0=Number bytes read
   int readMsg(char *msg, int maxSize);

   int peek(char *msg, int size);


private:

#ifdef REDHAT
   int      sock;
   int      sockServer;
   struct sockaddr_in   local, to;
#endif

#ifdef WIN32
   SOCKET   sock;
   SOCKET   sockServer;
   struct sockaddr_in   local, to;
#endif

};

#endif

--- End code ---


tcpSocket.cpp:

--- Code: ---#include "tcpSocket.h"

//--------------------------------------------------------------------------------
tcpSocket::tcpSocket()
{
   sock = INVALID_SOCKET;
   sockServer = INVALID_SOCKET;
}

//--------------------------------------------------------------------------------
tcpSocket::~tcpSocket()
{
}

//--------------------------------------------------------------------------------
int tcpSocket::openClient(unsigned short port, char *addr)
{
   if (port == 0) return TRUE;

#ifdef REDHAT
   int   flags;
   int   on=1;

   if (sock == INVALID_SOCKET) {

      bzero(&to, sizeof(to));
      to.sin_family = AF_INET;
      to.sin_port = htons( port );
      to.sin_addr.s_addr = inet_addr( addr );

      sock = socket(AF_INET, SOCK_STREAM, 0);
      if (sock == -1) {
         printf("ERROR - Unable to create socket\n");
         return TRUE;
      }

      // Enable Address Reuse
      setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
      // Enable No_Delay
      setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));

      if ( connect(sock, (const sockaddr*)&to, sizeof(to)) == -1 ) {
         printf("ERROR - Unable to connect to socket\n");
         return TRUE;
      }

      // Enable Non-blocking I/O
      flags = fcntl(sock, F_GETFL, 0);
      if ( fcntl(sock, F_SETFL, flags | FNONBLOCK) == -1 ) {
         printf("ERROR - Unable to set as nonblocking socket\n");
         return TRUE;
      }

   }
   return FALSE;
#endif

#ifdef WIN32
   int      stat;
   int      on=1;
   unsigned long onl=1;
   WSADATA  wsaData;

   if (sock == INVALID_SOCKET) {

      if ( WSAStartup( 0x202, &wsaData ) == SOCKET_ERROR ) {
         WSACleanup();
         return TRUE;
      }

      sock = socket( AF_INET, SOCK_STREAM, 0 );
      if ( sock < 0 ) {
         printf("ERROR - Opening socket\n");
         WSACleanup();
         return TRUE;
      }

      to.sin_family = AF_INET;
      to.sin_port = htons( port );
      to.sin_addr.s_addr = inet_addr( addr );

      // Enable Address Reuse (MUST be before the bind!)
      stat = setsockopt( sock,
                         SOL_SOCKET,
                         SO_REUSEADDR,
                         (const char *)&on,
                         sizeof(on) );
      if ( stat == SOCKET_ERROR ) {
         printf("ERROR - Unable to enable address reuse\n");
         closesocket( sock );
         WSACleanup();
         return TRUE;
      }

      stat = connect( sock,
                      (struct sockaddr *)&to,
                      sizeof(to) );
      if ( stat == SOCKET_ERROR ) {
         printf("ERROR - Connect to socket\n");
//         fprintf(stderr,"connect() failed: %d\n",WSAGetLastError());
         closesocket( sock );
         WSACleanup();
         return TRUE;
      }

      // Enable Non-blocking I/O
      stat = ioctlsocket( sock,
                          FIONBIO,
                          &onl );
      if ( stat == SOCKET_ERROR ) {
         printf("ERROR - Unable to enable Non-blocking I/O\n");
         return TRUE;
      }

   }
   return FALSE;
#endif

}

//--------------------------------------------------------------------------------
int tcpSocket::openServer(unsigned short port, char *addr)
{
   if (port == 0) return TRUE;

#ifdef REDHAT
   int   flags;
   int   on=1;
   int   len;
   struct sockaddr_in   clientAddr;

   if (sockServer == INVALID_SOCKET && sock == INVALID_SOCKET) {

      bzero(&local, sizeof(local));
      local.sin_family = AF_INET;
      local.sin_port = htons( port );
      local.sin_addr.s_addr = (in_addr_t)inet_addr("0.0.0.0");

      bzero(&to, sizeof(to));
      to.sin_family = AF_INET;
      to.sin_port = htons( port );
      to.sin_addr.s_addr = inet_addr( addr );

      sockServer = socket(AF_INET, SOCK_STREAM, 0);
      if (sockServer == INVALID_SOCKET) {
         printf("ERROR - Unable to create socket\n");
         return TRUE;
      }

      // Enable Address Reuse
      setsockopt(sockServer, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
      // Enable No_Delay
      setsockopt(sockServer, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));

      if ( bind(sockServer, (const sockaddr*)&local, sizeof(local)) == -1 ) {
         printf("ERROR - Unable to bind to socket\n");
         return TRUE;
      }

      if ( listen(sockServer,0) == -1) {
         printf("ERROR - Unable to listen to socket\n");
         return TRUE;
      }

      // Get client
      printf("Server waiting for client\n");
      len = sizeof(clientAddr);
      while (sock == INVALID_SOCKET) {
         sock = accept( sockServer,
                        (struct sockaddr *)&clientAddr,
                        (socklen_t *)&len );
      }
      printf("Accepted connection from %s, port %d\n",
                     inet_ntoa(clientAddr.sin_addr),
                     port) ;

      // Enable Non-blocking I/O
      flags = fcntl(sock, F_GETFL, 0);
      if ( fcntl(sock, F_SETFL, flags | FNONBLOCK) == -1 ) {
         printf("ERROR - Unable to set as nonblocking socket\n");
         return TRUE;
      }

   }
   return FALSE;
#endif

#ifdef WIN32
   int      stat;
   int      len;
   int      on=1;
   unsigned long onl=1;
   WSADATA  wsaData;
   struct sockaddr_in   clientAddr;

   if (sockServer == INVALID_SOCKET && sock == INVALID_SOCKET) {

      if ( WSAStartup( 0x202, &wsaData ) == SOCKET_ERROR ) {
         WSACleanup();
         return TRUE;
      }

      sockServer = socket( AF_INET, SOCK_STREAM, 0 );
      if ( sockServer < 0 ) {
         printf("ERROR - Opening socket\n");
         WSACleanup();
         return TRUE;
      }

      local.sin_family = AF_INET;
      local.sin_port = htons( port );
      local.sin_addr.s_addr = INADDR_ANY;

      to.sin_family = AF_INET;
      to.sin_port = htons( port );
      to.sin_addr.s_addr = inet_addr( addr );

      // Enable Address Reuse (MUST be before the bind!)
      stat = setsockopt( sockServer,
                         SOL_SOCKET,
                         SO_REUSEADDR,
                         (const char *)&on,
                         sizeof(on) );
      if ( stat == SOCKET_ERROR ) {
         printf("ERROR - Unable to enable address reuse\n");
         closesocket( sockServer );
         WSACleanup();
         return TRUE;
      }

      stat = bind( sockServer,
                   (struct sockaddr *)&local,
                   sizeof(local) );
      if ( stat == SOCKET_ERROR ) {
         printf("ERROR - Bind to socket\n");
         closesocket( sockServer );
         WSACleanup();
         return TRUE;
      }

      stat = listen( sockServer,
                     SOMAXCONN );
      if ( stat == SOCKET_ERROR ) {
         printf("ERROR - Listen to socket\n");
         closesocket( sockServer );
         WSACleanup();
         return TRUE;
      }

      // Get Client
      printf("Server waiting for client\n");
      len = sizeof(clientAddr);
      clientAddr.sin_port = 0;
      while (sock == INVALID_SOCKET) {
         sock = accept( sockServer,
                        (struct sockaddr *)&clientAddr,
                        &len );
      }
      printf("Accepted connection from %s, port %d\n",
                     inet_ntoa(clientAddr.sin_addr),
                     port) ;

      // Enable Non-blocking I/O
      stat = ioctlsocket( sock,
                          FIONBIO,
                          &onl );
      if ( stat == SOCKET_ERROR ) {
         printf("ERROR - Unable to enable Non-blocking I/O\n");
         return TRUE;
      }

   }
   return FALSE;
#endif

}

//--------------------------------------------------------------------------------
void tcpSocket::checkSocket(void)
{

#ifdef REDHAT
   int   len;
   int   flags;
   int   tempSock;
   struct sockaddr_in   clientAddr;

   // Enable Non-blocking I/O
   flags = fcntl(sockServer, F_GETFL, 0);
   fcntl(sockServer, F_SETFL, flags | FNONBLOCK);

   // Get Client
   len = sizeof(clientAddr);
   tempSock = accept( sockServer,
                      (struct sockaddr *)&clientAddr,
                      (socklen_t *)&len );
   if (tempSock != INVALID_SOCKET) {
      if (sock != INVALID_SOCKET) {
         shutdown(sock, 2);
         close(sock);
      }
      sock = tempSock;
   }
#endif

#ifdef WIN32
   int      len;
   unsigned long onl=1;
   SOCKET   tempSock;
   struct sockaddr_in   clientAddr;

   // Enable Non-blocking I/O
   ioctlsocket( sockServer, FIONBIO, &onl );

   // Get Client
   len = sizeof(clientAddr);
   clientAddr.sin_port = 0;
   tempSock = accept( sockServer,
                      (struct sockaddr *)&clientAddr,
                      &len );
   if (tempSock != INVALID_SOCKET) {
      if (sock != INVALID_SOCKET) {
         shutdown( sock, SD_BOTH );
         closesocket( sock );
      }
      sock = tempSock;
   }
#endif

}

//--------------------------------------------------------------------------------
void tcpSocket::closeSocket(void)
{

#ifdef REDHAT
   if (sockServer != INVALID_SOCKET) {
      shutdown(sockServer, 2);
      close(sockServer);
      sockServer = INVALID_SOCKET;
   }
   if (sock != INVALID_SOCKET) {
      shutdown(sock, 2);
      close(sock);
      sock = INVALID_SOCKET;
   }
#endif

#ifdef WIN32
   if (sockServer != INVALID_SOCKET) {
      shutdown( sockServer, SD_BOTH );
      closesocket( sockServer );
      sockServer = INVALID_SOCKET;
   }
   if (sock != INVALID_SOCKET) {
      shutdown( sock, SD_BOTH );
      closesocket( sock );
      sock = INVALID_SOCKET;
   }
   WSACleanup();
#endif

}

//--------------------------------------------------------------------------------
int tcpSocket::writeMsg(char *msg, int size)
{
   int   cnt;

   if (sock != INVALID_SOCKET) {
      cnt = sendto(sock, msg, size, 0, (struct sockaddr *)&to, sizeof(to));
      if (cnt == size) return cnt;
      else return -1;
   }
   return 0;
}

//--------------------------------------------------------------------------------
int tcpSocket::readMsg(char *msg, int maxSize)
{
   int   len;
   int   cnt;
   struct sockaddr_in   inSockAddr;

#ifdef REDHAT
   if (sock != INVALID_SOCKET) {
      len = sizeof(inSockAddr);
      cnt = recvfrom(sock, msg, maxSize, 0, (struct sockaddr *)&inSockAddr, (socklen_t *)&len);
      return cnt;
   }
#else
   if (sock != INVALID_SOCKET) {
      len = sizeof(inSockAddr);
      cnt = recvfrom(sock, msg, maxSize, 0, (struct sockaddr *)&inSockAddr, &len);
      return cnt;
   }
#endif
   return 0;
}

//--------------------------------------------------------------------------------
int tcpSocket::peek(char *msg, int size)
{
   int   len;
   int   cnt;
   struct sockaddr_in   inSockAddr;

#ifdef REDHAT
   if (sock != INVALID_SOCKET) {
      len = sizeof(inSockAddr);
      cnt = recvfrom(sock, msg, size, MSG_PEEK, (struct sockaddr *)&inSockAddr, (socklen_t *)&len);
      return cnt;
   }
#else
   if (sock != INVALID_SOCKET) {
      len = sizeof(inSockAddr);
      cnt = recvfrom(sock, msg, size, MSG_PEEK, (struct sockaddr *)&inSockAddr, &len);
      return cnt;
   }
#endif
   return 0;
}

//--------------------------------------------------------------------------------

--- End code ---


legacy:

--- Quote from: mrflibble on March 04, 2019, 12:27:37 am ---I notice that in config.h the port number is defined as 501. Certain problems might just go away when you change that to the carefully crafted port number of 10501.

--- End quote ---

On MachineA, it happens for every port I choose.
Neither 501 nor 10501 were already in use.


--- Quote from: mrflibble on March 04, 2019, 12:27:37 am ---Chances are pretty good that the bind() call in server.c returns -1.

--- End quote ---


--- Code: ---bind(listenfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr));

--- End code ---

bind return "0"  :-//

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version