Communication between 2 Socket listener on 2 different port with one program and server.

Jonathan Marler via Digitalmars-d digitalmars-d at puremagic.com
Tue Oct 11 17:41:38 PDT 2016


On Tuesday, 11 October 2016 at 16:59:56 UTC, vino wrote:
> Hi All,
>
>   Need your help, on the below request.
>
> Requirement:
> Server:
> 2 socket listening to 2 different ports with one main program
> 	Socket1 Port1 (Used for receiving user request(user data))
> 	Socket2 Port2 (Used for system request(system data))
>
> User request arrives via Socket1:Port1 needs to be sent 
> Socket2:Port2
> Once the request arrives then the request has to be sent to the 
> Manger(another server) via Socket2:Port2
>
> I was able to program to run multiple socket and send request 
> to Socket1:Port1 but not able to send the same request to 
> Socket2:Port2 tried both options sendTo and receiveFrom but no 
> luck.
>
> Note: the user request should to directly reach the 
> Manger(another server) it should is always follow the data 
> communication layer which is Socket2:Port2 as the
> server Manger will connect via Socket2:Port2(only) to receive 
> data.
>
>
> void main () {
> auto ext  = new Thread(&ext).start();
> auto int  = new Thread(&int).start();
> }
>
> void ext () {
> ushort extport  = 1120;
> Socket ext;
> char[1024] buf;
> Address mainserver = new InternetAddress("server1", 1121);
> ext = new TcpSocket();
> ext.bind(1120);
> ext.listen(1);
> ext.accpet();
> ext.receive(buf[]);
> writeln(buf[0..1024]);
> ext.sendTo(buf[0..1024], SocketFlags.NONE, mainserver);

There's quite a few things wrong with this, I'm guessing you 
don't have much experience with socket programming, but that's 
ok, everyone's gotta start somewhere. You should read some 
articles on socket programming, but I'll give you a few 
corrections for your example.

void ext () {
ushort extport  = 1120;

> Address mainserver = new InternetAddress("server1", 1121);
> ext = new TcpSocket();
> ext.bind(1120);
> ext.listen(1);

Not sure why you are using "server1" here, the listen address 
acts as a "filter" on where you accept connections from.  You 
probably want to allow connections from any ip address in which 
case you would want to pass the "any" address.  You probably want 
to create this socket more like this:

auto listenAddress = new 
InternetAddress(InternetAddress.ADDR_ANY, 1121);
Socket listenSocket = new Socket(listenAddress.family, 
SocketType.STREAM, ProtocolType.TCP);
listenSocket.bind(listenAddress);
listenSocket.listen(8); // lookup "listen" function to understand 
what the "backlog" argument is

Another common address to use is the LOOPBACK address, which 
means you only accept connections from the local machine (not 
from any remote machine)

> ext.accpet();

Here you've missed the fact that ext.accept actually returns the 
socket you can call send/receive on.  Here's what you should have 
done:

Socket dataSocket = listenSocket.accpet();

You can't actually send/receive data on the listen socket.  You 
will have 1 listen socket that's listening for connections.  
Every time you get a connection, the accept function will return 
a new socket that you can send/receive data with for that 
connection.

> ext.receive(buf[]);

If you call "receive" on the data socket, you are now blocking 
the listen socket from accepting more connections.  That may be 
ok for your application, but for some applications, they will 
start a new thread to handle the data socket, and put the listen 
socket accept into a loop, something like this:

while(true) {
     Socket dataSocket = listenSocket.accept();
     // now pass the data socket to a new thread and call receive 
on that thread
     // in the meantime, call accept again for any new connections 
that may come in
}

// The dataSocket thread can then call receive, and print the 
contents to the console like you had in your example.
void dataSocketThread()
{
     ubyte[1024] buf;
     auto received = dataSocket.receive(buf);
     writeln(buf[0..received]);
}

// Now if you want to send this data to the other listen socket, 
you'll need to create a new socket, call connect, then you can 
call send

Socket newDataSocket = new Socket(...).
newDataSocket.Connect(...)
newDataSocket.send(buf[0..received]);
newDataSocket.shtudown(SD_BOTH);
newDataSocket.close();

You cannot call "sendto" on a data socket.  sendto is for UDP 
sockets, which you are not using in this case.  For more 
information, lookup a tutorial on writing a UDP echo 
client/server.

Some more notes, if you don't to start a new thread every time 
you accept a new connection, you can use asynchronous IO.  You 
can start by learning the "select" function and work your way up 
to more complex apis.  Each OS has their own underlying 
mechanisms for async io, but there are also libraries you can use 
like libev, libevent, libuv.

There's alot to learn about socket programming, this is just the 
beginning.  I tried to throw together a fair bit of information 
in a little amount of time, hopefully you'll be able to take this 
information and build on it.  Good luck.




More information about the Digitalmars-d mailing list