www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Connecting python to D on socket of localhost : target machine

reply Enjoys Math <enjoysmath gmail.com> writes:
Here's my minimal D code (server.d):


module server;

import core.thread;
import std.socket;
import std.experimental.logger;


class Server : Thread
{
private:
	Socket listener;
	int backlog;
	string address;
	ushort port;
	SocketSet sockSet;
	Socket[] clients;
	bool running;

public:
	this(ushort port, string address="") {
		super(& run);
		
		if (address == "")
			address = "DESKTOP-T49RGUJ";

		this.port = port;
		this.address = address;
		backlog = int.max;
		listener = null;
		running = false;
	}

	bool setupSocket() {
		try {
			listener = new Socket(AddressFamily.INET, SocketType.STREAM);
			listener.bind(new InternetAddress(address, port));
			sockSet = new SocketSet();
		}
		catch (Exception e) {
			log(LogLevel.critical, e.toString());
			return false;
		}
		return true;
	}

	void start() {
		if (listener is null)
		{
			if (! setupSocket())
				return;
		}
		running = true;
		if (! isRunning) super.start();
	}

	void stop() {
		running = false;
	}

private:
	void run() {
		char[1024] buffer;

		while(running) {
			sockSet.reset();
			sockSet.add(listener);
			foreach (client; clients)
				sockSet.add(client);
				if (Socket.select(sockSet, null, null)) {
					foreach (client; clients)
					{
						if (sockSet.isSet(client)) {
							auto got = client.receive(buffer);
							client.send(buffer[0 .. got]);
						}
					}
					if (sockSet.isSet(listener)) {
						auto newSocket = listener.accept();
						newSocket.send("Hello!\n");
						clients ~= newSocket;
					}

				}
		}
	}
}


And here's the simple python client (main.py):


from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
import socket
import settings


if __name__ == "__main__":
     app = QApplication([])

     window = QMainWindow()
     window.show()

     host = socket.gethostname()
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     #sock.bind((host, 0))            # have os choose random 
available port
     print(host)
     sock.connect((host, settings.debugPort))

     try:

         # Send data
         message = 'This is the message.  It will be repeated.'
         print(sys.stderr, 'sending "%s"' % message)
         sock.sendall(message.encode())

         # Look for the response
         amount_received = 0
         amount_expected = len(message)

         while amount_received < amount_expected:
             data = sock.recv(16)
             amount_received += len(data)
             print(sys.stderr, 'received "%s"' % data)

     finally:
         print(sys.stderr, 'closing socket')
         sock.close()


     sys.exit(app.exec_())


---

The client throws:

builtins.ConnectionRefusedError: [WinError 10061] No connection 
could be made because the target machine actively refused it


Now, true this is python & D, but the client is generic and 
minimal so bear with me.

Thanks.

I've also tried 'localhost' on both sides.
Sep 21
next sibling parent reply Enjoys Math <enjoysmath gmail.com> writes:
I've tried opening the port for TCP with windows 10 firewall 
settings.  Same result.

What tool would best help me debug this?  Wireshark or is that 
too low level?
Sep 21
parent reply Enjoys Math <enjoysmath gmail.com> writes:
On Friday, 22 September 2017 at 04:25:00 UTC, Enjoys Math wrote:
 I've tried opening the port for TCP with windows 10 firewall 
 settings.  Same result.

 What tool would best help me debug this?  Wireshark or is that 
 too low level?
I've used Hercules: http://www.hw-group.com/products/hercules/index_en.html I set up a TCP server with it, and it got the message sent from python. Therefore there is something wrong with the D server.
Sep 21
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 22 September 2017 at 04:37:44 UTC, Enjoys Math wrote:
 On Friday, 22 September 2017 at 04:25:00 UTC, Enjoys Math wrote:
 I've tried opening the port for TCP with windows 10 firewall 
 settings.  Same result.

 What tool would best help me debug this?  Wireshark or is that 
 too low level?
I've used Hercules: http://www.hw-group.com/products/hercules/index_en.html I set up a TCP server with it, and it got the message sent from python. Therefore there is something wrong with the D server.
Could it be that you need to call `super(&run);` at the end of your constructor, after your data initialisation?
Sep 21
parent Enjoys Math <enjoysmath gmail.com> writes:
On Friday, 22 September 2017 at 05:43:24 UTC, Nicholas Wilson 
wrote:
 On Friday, 22 September 2017 at 04:37:44 UTC, Enjoys Math wrote:
 On Friday, 22 September 2017 at 04:25:00 UTC, Enjoys Math 
 wrote:
 I've tried opening the port for TCP with windows 10 firewall 
 settings.  Same result.

 What tool would best help me debug this?  Wireshark or is 
 that too low level?
I've used Hercules: http://www.hw-group.com/products/hercules/index_en.html I set up a TCP server with it, and it got the message sent from python. Therefore there is something wrong with the D server.
Could it be that you need to call `super(&run);` at the end of your constructor, after your data initialisation?
Nope, the run() method gets called.
Sep 21
prev sibling parent reply Sergei Degtiarev <sdegtiarev yahoo.com> writes:
On Friday, 22 September 2017 at 04:06:08 UTC, Enjoys Math wrote:
 Here's my minimal D code (server.d):
 public:
 	this(ushort port, string address="") {
 		super(& run);
 		
 		if (address == "")
 			address = "DESKTOP-T49RGUJ";

 		this.port = port;
 		this.address = address;
.........
 			listener.bind(new InternetAddress(address, port));
It seems to me, you pass invalid address to bind(). InternetAddress takes ipv4 dot notation string x.x.x.x, and for bind you are to supply INADDR_ANY
Sep 22
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 23/09/2017 3:26 AM, Sergei Degtiarev wrote:
 On Friday, 22 September 2017 at 04:06:08 UTC, Enjoys Math wrote:
 Here's my minimal D code (server.d):
 public:
     this(ushort port, string address="") {
         super(& run);

         if (address == "")
             address = "DESKTOP-T49RGUJ";

         this.port = port;
         this.address = address;
.........
             listener.bind(new InternetAddress(address, port));
It seems to me, you pass invalid address to bind(). InternetAddress takes ipv4 dot notation string x.x.x.x, and for bind you are to supply INADDR_ANY
For DNS resolution: https://dlang.org/phobos/std_socket.html#.getAddress
Sep 22
parent Sergei Degtiarev <sdegtiarev yahoo.com> writes:
On Saturday, 23 September 2017 at 02:50:25 UTC, rikki cattermole 
wrote:
 On 23/09/2017 3:26 AM, Sergei Degtiarev wrote:
 On Friday, 22 September 2017 at 04:06:08 UTC, Enjoys Math 
 wrote:
 Here's my minimal D code (server.d):
 public:
     this(ushort port, string address="") {
         super(& run);

         if (address == "")
             address = "DESKTOP-T49RGUJ";

         this.port = port;
         this.address = address;
.........
             listener.bind(new InternetAddress(address, port));
It seems to me, you pass invalid address to bind(). InternetAddress takes ipv4 dot notation string x.x.x.x, and for bind you are to supply INADDR_ANY
For DNS resolution: https://dlang.org/phobos/std_socket.html#.getAddress
Right, but in this case, it would be sufficient to bind socket to INADDR_ANY.
Sep 23