Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-连接套接字,客户端/服务器无关_Python_Sockets_Networking - Fatal编程技术网

Python-连接套接字,客户端/服务器无关

Python-连接套接字,客户端/服务器无关,python,sockets,networking,Python,Sockets,Networking,我想要两个进程在给定的端口上通信,其中一个没有定义的客户机或服务器角色。这两个进程中的任何一个都可能单独运行。任何一个都可以在任何时间以任何顺序停止和重新启动。当它们都在运行时,它们需要通信(当只有一个在运行时,通信被丢弃) 我需要非阻塞套接字和Windows/Linux支持。这里有一个相当粗糙的类,它实际上在某种程度上可以工作,这可能会让您开始学习 这里的主要诀窍是根本不用理会listen:它们是完全由对指定的纯对等连接 请注意,插座处于非阻塞模式。我捕获了recv异常,但也可能有send异常

我想要两个进程在给定的端口上通信,其中一个没有定义的客户机或服务器角色。这两个进程中的任何一个都可能单独运行。任何一个都可以在任何时间以任何顺序停止和重新启动。当它们都在运行时,它们需要通信(当只有一个在运行时,通信被丢弃)


我需要非阻塞套接字和Windows/Linux支持。

这里有一个相当粗糙的类,它实际上在某种程度上可以工作,这可能会让您开始学习

这里的主要诀窍是根本不用理会
listen
:它们是完全由对指定的纯对等连接

请注意,插座处于非阻塞模式。我捕获了
recv
异常,但也可能有
send
异常(另外,当发送到死掉的对等方时,会出现断管错误等)。您还需要处理来自终止对等方的EOF(当
recv
返回
'
而不是
EAGAIN失败时)


例如,使用:
$python peerish.py-p 9001-r 9002和python peerish.py-p 9002-r 9001&
运行。

该代码看起来与python完全不同。你的意思是这是伪代码吗?这是非常粗糙的伪代码…好吧,所以我想否决这个问题,原因如下:A.)这甚至不是一个问题。B.)显然你甚至没有为自己找到答案(或者,你很讨厌使用谷歌,这是一件让人感到羞耻和需要纠正的事情)C.)实际上是问题的问题并不是真正的问题(就像是字面上的问题,但它们缺乏任何意义“我想不出来——或者我试过做X为什么我做不到。”)。请不要把这种批评视为残忍或施虐的惩罚。-为拼写错误和诸如此类的事情感到抱歉。你是对的,我只是在试图解决这个问题之前懒洋洋地写了这个问题,认为一定是其他人已经解决了。(在谷歌上找不到解决方案。)。无论如何,我现在已经发布了自己的解决方案。UDP(又名SOCK_DGRAM,而不是SOCK_STREAM)是否适用于此应用程序?只需在UDP端口(n)上处理a接收,在UDP端口(n+1)上处理B接收即可,并让每一个都发送到另一个的UDP端口。这将为您提供所需的大部分质量,以及打包;唯一的缺点是偶尔会丢失一个数据包(在本地主机上不常见,但并非不可能),因此您的应用程序必须对此进行说明。这与同步有关:如果两个连接()尝试不会在几乎相同的时间触发,对等点无法正确连接。除了求助于实际的侦听器套接字之外,不确定如何修复此问题。
import errno
import os
import select
import socket

class Peer(object):
    def __init__(self, local_addr, peer_addr):
        self._local_addr = local_addr
        self._peer_addr = peer_addr
        self._renew()
        self.reopen()

    def _renew(self):
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.bind(self._local_addr)
        self._sock.setblocking(False)
        self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._state = 'bound'

    def is_open(self):
        return self._state == 'open'

    def is_opening(self):
        return self._state == 'opening'

    def reopen(self):
        if self._state == 'open':
            raise ValueError('already open')
        if self._state == 'opening':
            raise ValueError('open in progress')
        print 'try connect to:', self._peer_addr
        error = self._sock.connect_ex(self._peer_addr)
        print 'result:', error
        if error == 0:
            self._state = 'open'
            print 'connected immediately'
        elif error in (errno.EINPROGRESS, errno.EINTR):
            self._state = 'opening'
            print 'connection in progress'
        else:
            raise socket.error(error, os.strerror(error))

    def _check_open(self):
        if self._state != 'opening':
            raise ValueError('improper call to _check_open')
        print 'check connect to:', self._peer_addr
        _, wfds, _ = select.select([], [self._sock], [])
        if len(wfds) == 0:
            # connection still in progress
            return
        # we have a result: fail or succeed, either way a result
        try:
            peer = self._sock.getpeername()
        except socket.error as err:
            print 'caught err:', err
            if err.errno == errno.ENOTCONN:
                print 'connection failed, no peer available'
                self.close()
                return
            raise
        print 'got a peer:', peer
        self._state = 'open'
        print 'connection finished'

    def close(self):
        if self._state in ('open', 'opening'):
            self._sock.close()
            self._renew()
            # self.reopen() - or leave to caller

    def send_if_connected(self, data):
        # to do: add check for send to dead peer, and if so, _renew etc
        if self._state == 'bound':
            self.reopen()
        if self._state == 'opening':
            self._check_open()
        if self._state == 'open':
            self._sock.send(data)

    def recv_if_connected(self):
        # to do: add check for send to dead peer, and if so, _renew etc
        if self._state == 'bound':
            self.reopen()
        if self._state == 'opening':
            self._check_open()
        if self._state == 'open':
            try:
                return self._sock.recv(1024)
            except socket.error as err:
                # still connected but no data avail
                if err.errno == errno.EAGAIN:
                    return ''
                raise
        else:
            return None

if __name__ == '__main__':
    import argparse
    import time

    parser = argparse.ArgumentParser(description='test Peer()')
    parser.add_argument('-l', '--localhost', default='')
    parser.add_argument('-p', '--port', type=int, default=9001)
    parser.add_argument('-R', '--remote-host', default='')
    parser.add_argument('-r', '--remote-port', type=int, default=9002)
    args = parser.parse_args()

    x = Peer((args.localhost, args.port), (args.remote_host, args.remote_port))
    for i in range(1, 10):
        print 'attempt to send %d' % i
        x.send_if_connected('send %d' % i)
        got = x.recv_if_connected()
        if got is not None:
            print 'got: "%s"' % got
        time.sleep(1)