Products > Networking & Wireless
C networking, not working on 127.0.0.1
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
Go to full version