socket.sock()。bind()地址已在使用中

问题描述 投票:1回答:3

我正在尝试构建一个简单的服务器-客户端模型来执行文件传输任务。我的server.py和client.py看起来像这样:

<Server.py>
import socket

s = socket.socket()
host = socket.gethostname()
port = 1717
s.bind((host, port))
s.listen(1)
print(host)
print("Waiting for the client ...")

conn, addr = s.accept()
print(addr, "Connected!")

filename = "My file name"
file = open(filename, 'rb')
file_data = file.read(2048)
conn.send(file_data)
print("File has been sent to server.")
s.close()
<Client.py>
import socket
import time

time.sleep(3)

s = socket.socket()
host = "ubuntu"
port = 1717
s.connect((host, port))
print("Connected ....")

filename = "My file name"
file = open(filename, 'wb')
file_data = s.recv(2048)
file.write(file_data)
file.close()
print("File has been received.")

此外,我还编写了一个运行服务器和客户端的外壳文件,因为如果服务器在客户端之前运行,我只会报错,我在外壳脚本中这样写:

python3 ./some_path/server.py &
python3 ./some_path/client.py $n

注意,我也在Client.py的开头添加了time.sleep(3),因为我发现编写的shell脚本命令不能保证服务器先运行。现在,此问题已解决,但是,由于每次我想第二次运行整个程序时,由于server.py中的s.bind(),我收到了“已经在使用地址”错误。就是说,如果我打开Ubuntu并运行shell脚本,它就可以正常工作,并且一切都按预期进行。但是,当它完成并且我想再次运行时,我会得到“地址已经在使用中”。

所以我的问题是:

  1. 如何解决此问题,以便在不重新启动整个计算机的情况下测试功能。

  2. 有没有比我的time.sleep()方法更复杂的方法来使client.py始终在server.py之后运行?

  3. 还有其他更复杂的方法来获取主机名而不是预先指定吗?从client.py中可以看到,我基本上将主机设置为“ ubuntu”,因为这是从服务器端打印主机名时得到的。

非常感谢您阅读这个冗长的问题...我只是想让事情变得更清楚...非常感谢您能回答我的任何一个问题,甚至提出一些建议。顺便说一下,我正在ubuntu 14.04机器上测试所有这些。

python linux shell sockets ubuntu-14.04
3个回答
1
投票

首先,您还需要关闭客户端中的套接字。其次,您应该在关闭套接字之前调用shutdown。

请参阅此https://stackoverflow.com/a/598759/6625498


0
投票
  1. 尝试完全重新引导系统。这可能意味着该进程仍在运行。

0
投票
  1. 如何解决此问题,以便在不重新启动整个计算机的情况下测试功能。

    如果收到此消息“地址已在使用中,请在shell脚本上运行此命令”

    sudo killall -9 python3

    然后运行服务器和客户端。

  2. 有没有比我的time.sleep()方法更复杂的方法来使client.py总是在server.py之后运行?

  3. 请使用此代码。

server.py

import socket
import threading
import socketserver

socketserver.TCPServer.allow_reuse_address = True

__all__ = ['server']


class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
    def handle(self):
        cur_thread = threading.current_thread()
        requests = self.server.requests
        if self.request not in requests:
            requests[self.request] = {'client_id': cur_thread.ident,
                                      'client_address': self.client_address[0],
                                      'client_port': self.client_address[1]}

            if callable(self.server.onConnected):
                self.server.onConnected(self.request, self.server)
        while True:
            try:
                buffer = self.request.recv(my_constant.MSG_MAX_SIZE)
                if not buffer:
                    break
                buffer = str(binascii.hexlify(buffer))
                buffer = [buffer[i:i + 2] for i in range(2, len(buffer) - 1, 2)]

                self.server.onData(buffer, self.server, self.request) # process receive function
            except socket.error:
                print(str(socket.error))
                break
        if callable(self.server.onDisconnected) and (self.request in requests):
            self.server.onDisconnected(self.request, self.server)
        self.request.close()


class server(socketserver.ThreadingTCPServer):
    def __init__(self, host='', port=16838, *args, **kwargs):
        socketserver.ThreadingTCPServer.__init__(self, (host, port), ThreadedTCPRequestHandler)
        self.requests = {}
        self.server_thread = threading.Thread(target=self.serve_forever)
        self.server_thread.setDaemon(True)
        self.server_thread.start()
        self.onConnected = None
        self.onDisconnected = None
        self.onData = None

    def stop(self):
        self.quote_send_thread_stop = True

        for request in list(self.requests):
            self.shutdown_request(request)
            if self.onDisconnected:
                self.onDisconnected(request, self)
        self.shutdown()
        self.server_close()

    def broadcast(self, data):
        for request in list(self.requests):
            try:
                request.sendall(data)
            except socket.error:
                print(str(socket.error))
                del self.requests[request]

    def send(self, request, data):
        try:
            request.sendall(data)
        except socket.error:
            print(str(socket.error))
            del self.requests[request]

    def sendRaw(self, client_id, data):
        pass

    def disconnect(self, client_id):
        for request in list(self.requests):
            if client_id == self.requests[request]['client_id']:
                self.shutdown_request(request)
                if self.onDisconnected:
                    self.onDisconnected(request, self)
                else:
                    del self.requests[request]

def onConnected(request, server):
    try:
        print('[onConnected] client_address: ' + str(server.requests[request]))
    except Exception as e:
        print(str(e))

def onDisconnected(request, server):
    try:
        print('[onDisconnected] client_address: ' + str(server.requests[request]))
        del server.requests[request]
    except Exception as e:
        print(str(e))
def onData(request, server):
    #define your process message
    pass

main.py

his_server = server.server(sever_host, sever_port)
his_server.onConnected = server.onConnected
his_server.onDisconnected = server.onDisconnected
his_server.onData = server.onData

client.py

import socket
import time
from common.constant import *
from threading import Thread
import binascii
from .packet import *
import threading


def recv_msg(sock):
    while True:
        try:
            res = sock.recv(buf_size)
            if not res:
                continue
            buffer = str(binascii.hexlify(res))
            buffer = [buffer[i:i + 2] for i in range(2, len(buffer) - 1, 2)]

            #packet parsing, you maybe change this part.
            packet_parsing(buffer)
            time.sleep(0.100)
        except socket.error:
            print(str(socket.error))
            break

class history_thread(threading.Thread):
    def __init__(self, threadID, name, delay, server, port):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.delay = delay
        self.server = server
        self.port = port
        self.sock = None
    def run(self):
        print("Starting " + self.name)

        while True:
            try:
                self.sock = socket.socket()
                self.sock.connect((self.server, self.port))

                tc = Thread(target=recv_msg, args=(self.sock,))
                tc.start()
                threads = []
                threads.append(tc)
                for pip in threads:
                    pip.join()
                self.sock.close()
                self.sock = None
            except socket.error:
                print(str(socket.error))
                if self.sock is not None:
                    self.sock.close()
                self.sock = None
            time.sleep(self.delay)

    def send(self, data):
        if self.sock is None:
            return -1
        try:
            self.sock.sendall(data)
        except:
            print(str(socket.error))
© www.soinside.com 2019 - 2024. All rights reserved.