坪山商城网站建设哪家便宜,asp.net做电商网站设计,ui设计师怎么做简历网站,山东东营市旅游景点大全关于端口复用一个套接字不能同时绑定多个端口#xff0c;如果客户端想绑定端口号#xff0c;一定要调用发送信息函数之前绑定( bind )端口#xff0c;因为在发送信息函数( sendto, 或 write )#xff0c;系统会自动给当前网络程序分配一个随机端口号#xff0c;这相当于随…关于端口复用一个套接字不能同时绑定多个端口如果客户端想绑定端口号一定要调用发送信息函数之前绑定( bind )端口因为在发送信息函数( sendto, 或 write )系统会自动给当前网络程序分配一个随机端口号这相当于随机绑定了一个端口号这里只会分配一次以后通信就以这个随机端口通信我们再绑定端口号的话就会绑定失败。如果我们放在发送信息函数( sendto, 或 write )之前绑定那样程序将以我们绑定的端口号发送信息不会再随机分配一个端口号。实际上默认的情况下如果一个网络应用程序的一个套接字 绑定了一个端口这时候别的套接字就无法使用这个端口。那如何让两个套接字都能成功绑定一个端口呢?这时候就需要要到端口复用了。端口复用允许在一个应用程序可以把 n 个套接字绑在一个端口上而不出错。端口复用能在系统已开放的端口上进行通讯只对输入的信息进行字符匹配不对网络数据进行任何拦截、复制类操作所以对网络数据的传输性能丝毫不受影响。但要注意建立连接后服务端程序占用极少系统资源被控端不会在系统性能上有任何察觉通常被后门木马所利用。在winsock的实现中对于服务器的绑定是可以多重绑定的在确定多重绑定使用谁的时候根据一条原则是谁的指定最明确则将包递交给谁而且没有权限之分也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。Python解决UDP端口复用问题一直觉得UDP协议很简单但是今天问题让我感觉到网络的基础真是博大精深。废话少说来看问题吧。由于协议的需要我得实现一个UDP的客户端和服务器端并且从同一个端口读写数据。最初不以为然无非就是用两个socket一个监听并从这个端口读取数据(服务器端采用了twisted)另一个向这个端口写入数据用python实现只要10行左右的代码。def startServer(queue, port):reactor.listenUDP(port, DhtResponseHandler(queue))reactor.run()def sendUdpMsg(self, addr, msg):socketHandler socket.socket(socket.AF_INET, socket.SOCK_DGRAM)socketHandler.bind((, self.port))socketHandler.sendto(msg, addr)socketHandler.close()由于要向同一个端口写数据于是client必须有bind但是运行后发现server先bind了这个端口client运行时会报错error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted一般这种错误时因为多个socket不能同时bind同一个地址由于基础不够扎实我开始疯狂的搜索发现有人说端口复用的问题所谓的端口复用是指一个套接字释放掉一个端口后有一个wait_time另一个套接字如果接着bind就会报错。虽然我的问题不完全一样但是我欣喜若狂的使用了。即在client bind前加上如下一句socketHandler.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)但是仍然报错error: [Errno 10013] An attempt was made to access a socket in a way forbidden by its access permissions(顺便一提还有另一个参数叫SO_REUSEPORT即复用端口另外有一个叫SO_EXCLUSIVEADDRUSE即不准复用该端口其他socket的参数还有很多可以参考winsockhttp://msdn.microsoft.com/en-us/library/aa924071.aspx或者unix下的socket)这个10013错误让我百思不得其解搜索一下主要有两种解释有人说是需要提升应用程序的权限为管理员我用的是eclipsepydev提升完eclipse权限没用实际上还要修改python.exe的权限方法是在这个程序上右键兼容性一栏中勾上以系统管理员身份运行有人说是跟其他程序地址或者端口冲突。但是我测试过发现都不行。另外运行的时候发现twisted的服务器端一定是要在主线程中否则会报signal一定要在主线程才能接受的错误但是twisted的reactor一运行起来就阻塞了。在twisted文档中翻到原来还有一种UDP叫做connected UDP变态吧所谓connected UDP就是只能向一个地址收发数据看起来貌似可以但是不符合可以向多个地址接收数据。最后在一篇文章中翻到说需要两个端口都设置重用于是我试着重新写一个服务器与之前的客户端配合运行良好完全无错sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM)sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)sock.bind((, port))data, address sock.recvfrom(4096)好吧看来问题在调用twisted了不知道他是否有这样的设置进去将这部分代码翻了一下找不到这样设置的参数。class Port(abstract.FileHandle):def __init__(self, port, proto, interface, maxPacketSize8192,reactorNone):Initialize with a numeric port to listen on.self.port portself.protocol protoself.readBufferSize maxPacketSizeself.interface interfaceself.setLogStr()self._connectedAddr Noneabstract.FileHandle.__init__(self, reactor)skt socket.socket(self.addressFamily, self.socketType)addrLen _iocp.maxAddrLen(skt.fileno())self.addressBuffer _iocp.AllocateReadBuffer(addrLen)# WSARecvFrom takes an intself.addressLengthBuffer _iocp.AllocateReadBuffer(struct.calcsize(i))def startListening(self):Create and bind my socket, and begin listening on it.This is called on unserialization, and must be called after creating aserver to begin listening on the specified port.self._bindSocket()self._connectToProtocol()def createSocket(self):return self.reactor.createSocket(self.addressFamily, self.socketType)def _bindSocket(self):try:skt self.createSocket()skt.bind((self.interface, self.port))except socket.error, le:raise error.CannotListenError, (self.interface, self.port, le)# Make sure that if we listened on port 0, we update that to# reflect what the OS actually assigned us.self._realPortNumber skt.getsockname()[1]log.msg(%s starting on %s % (self._getLogPrefix(self.protocol), self._realPortNumber))self.connected Trueself.socket sktself.getFileHandle self.socket.fileno难道说twisted就完全不提供这样的功能最终在multicast中翻到这样一段也就是多播的情况是支持地址复用的动手测起来。class MulticastPort(MulticastMixin, Port):UDP Port that supports multicasting.implements(interfaces.IMulticastTransport)def __init__(self, port, proto, interface, maxPacketSize8192,reactorNone, listenMultipleFalse):Port.__init__(self, port, proto, interface, maxPacketSize, reactor)self.listenMultiple listenMultipledef createSocket(self):skt Port.createSocket(self)if self.listenMultiple:skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)if hasattr(socket, SO_REUSEPORT):skt.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)return skt将server端改成如下代码运行通过reactor.listenMulticast(port, DhtResponseHandler(queue), listenMultipleTrue)reactor.run()感触良多底层的知识比较重要浮沙筑高台果然危险。