python-vxi11-server icon indicating copy to clipboard operation
python-vxi11-server copied to clipboard

OSError: [WinError 10049] The requested address is not valid in its context.

Open chenchen1992223 opened this issue 2 years ago • 7 comments

Hello, I encountered this problem while starting the server,Looking forward to receiving your response image

INFO:main:starting time_device INFO:vxi11_server.instrument_server:abortServer started... ERROR:vxi11_server.rpc:Error: rpcbind -i not running? [WinError 10049] The requested address is not valid in its context.。 Traceback (most recent call last): File "D:\111\PycharmProjects\python-vxi11-server-master\python-vxi11-server-master\vxi11_server\rpc.py", line 726, in register self.register_pmap() File "D:\111\PycharmProjects\python-vxi11-server-master\python-vxi11-server-master\vxi11_server\rpc.py", line 734, in register_pmap p = TCPPortMapperClient(host) File "D:\111\PycharmProjects\python-vxi11-server-master\python-vxi11-server-master\vxi11_server\rpc.py", line 499, in init RawTCPClient.init(self, host, PMAP_PROG, PMAP_VERS, PMAP_PORT) File "D:\111\PycharmProjects\python-vxi11-server-master\python-vxi11-server-master\vxi11_server\rpc.py", line 263, in init self.connect() File "D:\111\PycharmProjects\python-vxi11-server-master\python-vxi11-server-master\vxi11_server\rpc.py", line 267, in connect self.sock.connect((self.host, self.port)) OSError: [WinError 10049] The requested address is not valid in its context.。

chenchen1992223 avatar Mar 17 '23 08:03 chenchen1992223

The key clue in this error chain is the message ERROR:vxi11_server.rpc:Error: rpcbind -i not running? which indicates that the rpc portmapper is not running. RPC is an underlying library that is typically supplied by the OS and that most RPC client/servers (including vxi11) rely upon. It appears you are running windows which complicates things a bit...

Please investigate issue https://github.com/coburnw/python-vxi11-server/issues/2 for how Raphael managed to get rpc running in a windows environment.

coburnw avatar Mar 17 '23 17:03 coburnw

The key clue in this error chain is the message ERROR:vxi11_server.rpc:Error: rpcbind -i not running? which indicates that the rpc portmapper is not running. RPC is an underlying library that is typically supplied by the OS and that most RPC client/servers (including vxi11) rely upon. It appears you are running windows which complicates things a bit...

Please investigate issue #2 for how Raphael managed to get rpc running in a windows environment.

Thank you for your answer. I apologize for taking so long to reply. I would like to write my own portmap service that can be executed on Win. However, after starting it, I found that the service was unable to discover the current portmap service. Could you please help me take a look,This is a demo program and there may be errors

import socket
import struct

class VXI11PortmapServer:
    def __init__(self, port=111):
        self.port = port
        self.services = {}

    def register_service(self, service_name, service_port):
        self.services[service_name] = service_port

    def unregister_service(self, service_name):
        if service_name in self.services:
            del self.services[service_name]

    def start(self):
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
            sock.bind(('0.0.0.0', self.port))
            while True:
                data, addr = sock.recvfrom(1024)
                rpc_version, msg_type, rpc_call_id, prog, vers, proc, cred, verf = struct.unpack('!IIIIIIII', data[:32])
                # if prog == 0x39584130 and vers == 1 and proc == 0:
                if prog == 100000 and vers == 2 and proc == 0:

                    # Portmap GETPORT request
                    service_name = data[48:].decode('utf-8').rstrip('\0')
                    if service_name in self.services:
                        service_port = self.services[service_name]
                        response = struct.pack('!IIIIIIII', 2, 1, rpc_call_id, 0, 0, 0, 0, 0)
                        response += struct.pack('!IIII', 0, 0, 0, service_port)
                        sock.sendto(response, addr)
                elif prog == 100000 and vers == 2 and proc == 2:
                    # Portmap SET mapping request
                    service_name = data[:data.index(b'\x00')].decode('utf-8')
                    data = data[data.index(b'\x00') + 1:]
                    service_port = struct.unpack('!I', data[:4])[0]
                    self.services[service_name] = service_port
                    response = struct.pack('!IIIIIIII', 2, 1, rpc_call_id, 0, 0, 0, 0, 0)
                    response += struct.pack('!IIII', 0, 0, 0, 0)
                    sock.sendto(response, addr)
                elif prog == 100000 and vers == 2 and proc == 3:
                    # Portmap UNSET mapping request
                    service_name = data[48:].decode('utf-8').rstrip('\0')
                    if service_name in self.services:
                        del self.services[service_name]
                    response = struct.pack('!IIIIIIII', 2, 1, rpc_call_id, 0, 0, 0, 0, 0)
                    response += struct.pack('!IIII', 0, 0, 0, 0)
                    sock.sendto(response, addr)

if __name__ == '__main__':
    server = VXI11PortmapServer()
    server.start()

chenchen1992223 avatar Jun 01 '23 11:06 chenchen1992223

Interesting idea!

You might consider opening a new github repository named, perhaps, 'pyRPCBind'. I suspect it might have a wider interest than just vxi11 users.

Do you have access to a formal running version of rpcbind on another machine that you can test against? If not i would be willing to cobble together a minimal client that works well with linux's native rpcbind that you could then use against your pyrpcbind for testing.

Have you tried a packet analysis application such as wireshark to view the low level interaction between your test client and your server? It looks like you found RFC1833, so you are well on your way.

My time is limited for any new projects. But i would like to help where i can.

coburnw avatar Jun 01 '23 18:06 coburnw

Excuse me. vxi-11 supports multiple clients. I understand that each client corresponds to a link_id. However, in the code, only one link_id is used after create_link. For example, device 0 is used. I have two clients connected at the same time, and the corresponding two link_ids can take effect. However, according to the current code, if one client is connected, the other client will overwrite the original client if it does not exit. I don't know if my understanding is wrong. Looking forward to your reply

chenchen1992223 avatar Jun 25 '23 09:06 chenchen1992223

Since link_id doesnt seem to be part of the portmapper process, im going to assume you have a python portmapper of your creation running on your pc. Pretty cool!

So, focusing on the VXI-11 libraries, each vxi11 client should receive a unique link_id when creating a link on a vxi11 device as here https://github.com/coburnw/python-vxi11-server/blob/9f53707dfd5bf553f64070320e7d0bb20b27c72a/vxi11_server/instrument_server.py#L193

  • If you are in fact getting duplicate link_id's then there may be a bug that should be addressed.
  • If each client is getting a unique link_id as it should and you are finding that clients are corrupting each other, then you might look at having your clients request a lock on the device, see section 'B.4.1.Multiple Controllers' and 'B.4.2.Locking' of the 'VXI-11 TCP/IP Instrument Protocol Specification'
  • If you want two clients to concurrently access the same device, then you will need to code your device to properly handle that.

I havent played much with locking in this library so there may be latent bugs or misunderstandings. But i would be surprised if you find that clients are getting duplicate link_ids. Please be sure to report back with sample code if you find that is the case.

coburnw avatar Jun 25 '23 21:06 coburnw

Since link_id doesnt seem to be part of the portmapper process, im going to assume you have a python portmapper of your creation running on your pc. Pretty cool!

So, focusing on the VXI-11 libraries, each vxi11 client should receive a unique link_id when creating a link on a vxi11 device as here

https://github.com/coburnw/python-vxi11-server/blob/9f53707dfd5bf553f64070320e7d0bb20b27c72a/vxi11_server/instrument_server.py#L193

  • If you are in fact getting duplicate link_id's then there may be a bug that should be addressed.
  • If each client is getting a unique link_id as it should and you are finding that clients are corrupting each other, then you might look at having your clients request a lock on the device, see section 'B.4.1.Multiple Controllers' and 'B.4.2.Locking' of the 'VXI-11 TCP/IP Instrument Protocol Specification'
  • If you want two clients to concurrently access the same device, then you will need to code your device to properly handle that.

I havent played much with locking in this library so there may be latent bugs or misunderstandings. But i would be surprised if you find that clients are getting duplicate link_ids. Please be sure to report back with sample code if you find that is the case.

I'm sorry to bother you again. I'm writing the vxi-11 core function, create_intr_channel. I have any questions. I hope I can get your answer to help me solve the puzzle,

  1. Is this function used to construct a vxi-11 client on the server to connect to another vxi-11 server at the remote end?
  2. If yes, why is the port parameter specified? Isn't the client getting the port parameter in the portmap? If not, what is it?
  3. If create_intr_channel is to build a vxi-11 client in the vxi-11 server to connect to the remote end, do I send commands and read results by using the two core functions device_write and device_read? I don't see such an implementation in the Python implementation. Maybe I don't understand it well enough. Therefore, I want to know which function to use to implement command communication if an interrupt channel is built, because I see in the official document. Seems to be using the device_write function I'm sorry to bother you again, but I'm looking forward to your answer. As a rookie, I'm looking forward to it.

chenchen1992223 avatar Jul 20 '23 09:07 chenchen1992223

Since link_id doesnt seem to be part of the portmapper process, im going to assume you have a python portmapper of your creation running on your pc. Pretty cool! So, focusing on the VXI-11 libraries, each vxi11 client should receive a unique link_id when creating a link on a vxi11 device as here https://github.com/coburnw/python-vxi11-server/blob/9f53707dfd5bf553f64070320e7d0bb20b27c72a/vxi11_server/instrument_server.py#L193

  • If you are in fact getting duplicate link_id's then there may be a bug that should be addressed.
  • If each client is getting a unique link_id as it should and you are finding that clients are corrupting each other, then you might look at having your clients request a lock on the device, see section 'B.4.1.Multiple Controllers' and 'B.4.2.Locking' of the 'VXI-11 TCP/IP Instrument Protocol Specification'
  • If you want two clients to concurrently access the same device, then you will need to code your device to properly handle that.

I havent played much with locking in this library so there may be latent bugs or misunderstandings. But i would be surprised if you find that clients are getting duplicate link_ids. Please be sure to report back with sample code if you find that is the case.

I'm sorry to bother you again. I'm writing the vxi-11 core function, create_intr_channel. I have any questions. I hope I can get your answer to help me solve the puzzle,

  1. Is this function used to construct a vxi-11 client on the server to connect to another vxi-11 server at the remote end?
  2. If yes, why is the port parameter specified? Isn't the client getting the port parameter in the portmap? If not, what is it?
  3. If create_intr_channel is to build a vxi-11 client in the vxi-11 server to connect to the remote end, do I send commands and read results by using the two core functions device_write and device_read? I don't see such an implementation in the Python implementation. Maybe I don't understand it well enough. Therefore, I want to know which function to use to implement command communication if an interrupt channel is built, because I see in the official document. Seems to be using the device_write function I'm sorry to bother you again, but I'm looking forward to your answer. As a rookie, I'm looking forward to it.

image

chenchen1992223 avatar Jul 20 '23 09:07 chenchen1992223