C networking, not working on 127.0.0.1 - Page 1
Forum section: electronics / general

author: legacy
author_rank: Super Contributor
timestamp: March 03, 2019, 08:03:52 pm
content: so I have these two examples, a simpleserverand a simpleclient(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.1Sun Mar 3 17:32:18 2019./client 192.168.1.81Sun Mar 3 17:32:46 2019MachineB(ip=192.168.1.24):Code:./server &./client 127.0.0.1^C./client 192.168.1.24^Cthe client was blocked, so I terminated the client by pressing CTRL + CMachineB, connecting to MachineACode:./client 192.168.1.81Sun Mar 3 17:32:46 2019so ... I am a bit perplexed

author: mrflibble
author_rank: Super Contributor
timestamp: March 04, 2019, 12:27:37 am
content: Presumably because you try to listen on a privileged port?I notice that inconfig.hthe 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 thebind()call inserver.creturns -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 VALUEOn 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.

author: ejeffrey
author_rank: Super Contributor
timestamp: March 04, 2019, 03:26:42 am
content: 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.

author: MarkF
author_rank: Super Contributor
timestamp: March 04, 2019, 04:43:32 am
content: 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>#endifclass 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 writtenint writeMsg(char *msg, int size);// READ MESSAGE// Return: -1=Error reading message, 0=No message, >0=Number bytes readint readMsg(char *msg, int maxSize);int peek(char *msg, int size);private:#ifdef REDHATint sock;int sockServer;struct sockaddr_in local, to;#endif#ifdef WIN32SOCKET sock;SOCKET sockServer;struct sockaddr_in local, to;#endif};#endiftcpSocket.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 REDHATint 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 Reusesetsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));// Enable No_Delaysetsockopt(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/Oflags = 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 WIN32int 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/Ostat = 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 REDHATint 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 Reusesetsockopt(sockServer, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));// Enable No_Delaysetsockopt(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 clientprintf("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/Oflags = 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 WIN32int 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 Clientprintf("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/Ostat = 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 REDHATint len;int flags;int tempSock;struct sockaddr_in clientAddr;// Enable Non-blocking I/Oflags = fcntl(sockServer, F_GETFL, 0);fcntl(sockServer, F_SETFL, flags | FNONBLOCK);// Get Clientlen = 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 WIN32int len;unsigned long onl=1;SOCKET tempSock;struct sockaddr_in clientAddr;// Enable Non-blocking I/Oioctlsocket( sockServer, FIONBIO, &onl );// Get Clientlen = 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 REDHATif (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 WIN32if (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 REDHATif (sock != INVALID_SOCKET) {len = sizeof(inSockAddr);cnt = recvfrom(sock, msg, maxSize, 0, (struct sockaddr *)&inSockAddr, (socklen_t *)&len);return cnt;}#elseif (sock != INVALID_SOCKET) {len = sizeof(inSockAddr);cnt = recvfrom(sock, msg, maxSize, 0, (struct sockaddr *)&inSockAddr, &len);return cnt;}#endifreturn 0;}//--------------------------------------------------------------------------------int tcpSocket::peek(char *msg, int size){int len;int cnt;struct sockaddr_in inSockAddr;#ifdef REDHATif (sock != INVALID_SOCKET) {len = sizeof(inSockAddr);cnt = recvfrom(sock, msg, size, MSG_PEEK, (struct sockaddr *)&inSockAddr, (socklen_t *)&len);return cnt;}#elseif (sock != INVALID_SOCKET) {len = sizeof(inSockAddr);cnt = recvfrom(sock, msg, size, MSG_PEEK, (struct sockaddr *)&inSockAddr, &len);return cnt;}#endifreturn 0;}//--------------------------------------------------------------------------------

author: legacy
author_rank: Super Contributor
timestamp: March 04, 2019, 10:30:56 am
content: Quote from: mrflibble on March 04, 2019, 12:27:37 amOn 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 amCode:bind(listenfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr));bind return "0"

author: legacy
author_rank: Super Contributor
timestamp: March 04, 2019, 10:43:59 am
content: Quote from: ejeffrey on March 04, 2019, 03:26:42 amCode:netstat -lActive Internet connections (only servers)Proto Recv-Q Send-Q Local Address Foreign Address Statetcp 0 0 0.0.0.0:10501 0.0.0.0:* LISTENtcp 0 0 0.0.0.0:ftp 0.0.0.0:* LISTENtcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTENtcp6 0 0 [::]:ssh [::]:* LISTENActive UNIX domain sockets (only servers)Proto RefCnt Flags Type State I-Node Pathunix 2 [ ACC ] STREAM LISTENING 150 /tmp/screen/S-root/1813.console.OrangeCubeunix 2 [ ACC ] STREAM LISTENING 10606478 /tmp/ssh-07m4yNlPiz/agent.32253unix 2 [ ACC ] STREAM LISTENING 10602276 /tmp/ssh-r2fGrglbIw/agent.1366Code:tcp 0 0 0.0.0.0:10501 0.0.0.0:* LISTENthis is ./server, so there is "something" listening on the 10501 port.In fact, if machineB tries to connect to this server running on MachineA: it works!The problem is that a client on MachineA cannot connect to the server running on MachineAso ./client 127.0.0.1 doesn't work, neither ./client 192.168.1.24 (which is the IP of machineA)QuoteCode:netstat -npActive Internet connections (w/o servers)Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program nametcp 0 0 192.168.1.24:22 192.168.1.12:1528 ESTABLISHED 32266/sshd: root@notcp 0 0 192.168.1.24:22 192.168.1.12:1176 ESTABLISHED 1366/sshd: root@ptstcp 0 72 192.168.1.24:22 192.168.1.12:1526 ESTABLISHED 32253/sshd: root@pttcp 0 0 192.168.1.24:22 192.168.1.12:1178 ESTABLISHED 1400/sshd: root@notActive UNIX domain sockets (w/o servers)Proto RefCnt Flags Type State I-Node PID/Program name Pathunix 2 [ ] STREAM CONNECTED 5335445 9038/sshd: root@notunix 2 [ ] STREAM CONNECTED 10603692 32253/sshd: root@ptunix 2 [ ] STREAM CONNECTED 10599293 1400/sshd: root@notunix 2 [ ] STREAM CONNECTED 10599278 1366/sshd: root@ptsunix 2 [ ] STREAM CONNECTED 10603719 32266/sshd: root@noQuoteQuoteI will fix.

author: legacy
author_rank: Super Contributor
timestamp: March 04, 2019, 10:59:37 am
content: Quote from: MarkF on March 04, 2019, 04:43:32 amThanks! This will be certainly helpful in the futureI am trying to investigate certain programs (not written by me) that suddenly stopped to work once moved and recompiled on MachineA (it's a Pentium4 @ 3Ghz, loaded with Linux 32bit, running kernel v4.9.16). They are basically TCP/IP servers, and basically, they do not work when the client tries to connect to 127.0.0.1, that was the original problem subjected to my attention. So I wrote a super simple POC, with a couple of super simple client and server, for checking what is wrong.It *might* be also something with the kernel: cannot be excluded!

author: stmdude
author_rank: Frequent Contributor
timestamp: March 04, 2019, 11:14:27 am
content: Are sure your "lo" interface is up ?

author: bd139
author_rank: Super Contributor
timestamp: March 04, 2019, 11:45:30 am
content: If you're on a Redhat or Ubuntu derivative, check that SELinux or AppArmor isn't being a dick as well. But always check those API return values!

author: legacy
author_rank: Super Contributor
timestamp: March 04, 2019, 01:03:02 pm
content: Quote from: stmdude on March 04, 2019, 11:14:27 ambingoit seems there was a mistake with one of the bootstrapping script, resulting in the local loopback not properly configuredCode:ifconfig lolo: flags=8<LOOPBACK> mtu 65536loop txqueuelen 1 (Local Loopback)RX packets 0 bytes 0 (0.0 B)RX errors 0 dropped 0 overruns 0 frame 0TX packets 0 bytes 0 (0.0 B)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0So I tried thisCode:ifconfig lo 127.0.0.1and now ./client 127.0.0.1 works!

author: SiliconWizard
author_rank: Super Contributor
timestamp: March 04, 2019, 05:18:28 pm
content: Additionally, I suggest checking *all* return values. And in case of error, you can then check/print 'errno' which will give you a much better hint as to what is wrong than just '-1'.

author: bd139
author_rank: Super Contributor
timestamp: March 04, 2019, 05:34:11 pm
content: Disclaimer: don't do ths if it looks like a rootkit