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