I'm having fun here in Ireland trying to develop a Video and Sound Chat Room
I'm using Visual C++ under Windows 7 for the Client
and C and Linux for the server.
and UDP for the router bypass technology
I seem to have hit a dead end with the external port numbers
If I get a window client (behind a router) to access a WINDOWS server, the server can get the
external port number and contact the client through the router. That's easy. I can even write a second program and access the client that's behind the router using the same external port number.
Similarly if I get the windows client (behind the router) to access the LINUX server the Linux server can do exactly the same thing and make contact with the calling program using the external port number, and again I can stop the server and use another little program and contact the client behind the router by using the same external port number.
Here's the hassle
I want to get the windows client (behind the router) to access the linux server, the linux server to ascertain the external port number and then use that external port number to access the calling program FROM ANOTHER WINDOWS CLIENT.
The trouble is Linux established the external port number it can only be used in linux and if windows establishes it, it can only be used in windows.
The two systems must be holding the port numbers in a different format
I have tried ntohs and htons as they sort out an 'endian' problem. I certainly thought that they would provide the solution but they do not.
There must be a very simple solution to this as without it nobody could have windows clients and linux servers.
I'd be very grateful if anybody could point me to a worked example but I have looked for quite some time and this one eludes me yet.
Peadar Dublin, Ireland Tuesday, December 2 2014
====================================================================
This is the Windows Server Code
memset((
char*) &si_me, 0,sizeof(si_me));
si_me.sin_family =
AF_INET;
si_me.sin_port = htons(
PORT);
si_me.sin_addr.
s_addr= htonl(INADDR_ANY);
if(bind(ServSock, (structsockaddr*)(&si_me),sizeof(si_me))==-1)
{
AfxMessageBox(
"problemwith bind");
WSACleanup();
diep(
"bind");
}
if(recvfrom(ServSock, buf,BUFLEN, 0, (structsockaddr*)(&si_other),&slen)==-1)
{
AfxMessageBox(
"problemwith recvfrom");
WSACleanup();
diep(
"recvfrom");
}
sprintf_s(ErrLine,
"Received packet from %s:%d\n", inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
AfxMessageBox(ErrLine);
WSACleanup();
closesocket(ServSock);
====================================================================
This is the Linux Server Code
struct sockaddr_in my_addr;
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(real_port);
my_addr.sin_addr.s_addr = INADDR_ANY;
int bindret = bind(fd, (const struct sockaddr *)&my_addr, sizeof(my_addr));
if (bindret < 0)
{
fprintf(stderr, "Unable to bind to port %d. errno %d\n", port, errno);
return 7;
}
uint32_t * last_addr;
uint16_t * last_port;
char buf[sizeof(*last_addr) + sizeof(*last_port)];
memset(buf, 0, sizeof(buf));
last_addr = (uint32_t *) (buf );
last_port = (uint16_t *) (last_addr + 1);
uint32_t iter;
struct sockaddr_in next_data;
socklen_t next_len = sizeof(next_data);
memset(&next_data, 0, sizeof(next_data));
ssize_t recvret = recvfrom(fd, NULL, 0, MSG_TRUNC, (struct sockaddr *) &next_data, &next_len);
if (recvret < 0)
{
printf("Error on recvfrom. errno %d\n", errno); fflush(stdout);
return 3;
}
inet_ntop(AF_INET, &next_data.sin_addr.s_addr, TmpString, INET_ADDRSTRLEN);
printf( " \n\nthe port that we are using to send stuff back is %d \n\n" ,next_data.sin_port); fflush(stdout);
printf( " \n\nthe ntohs converted version is %d \n\n" ,ntohs(next_data.sin_port)); fflush(stdout);
close (fd);
return 0;
}
====================================================================