无法实现与服务器的同时连接

时间:2017-01-09 14:39:16

标签: java multithreading sockets server

我有一个java服务器(java 1.6,如果它有帮助)接受套接字连接,然后启动线程来解决它们,就像任何常规的多线程服务器一样。但我无法同时进行连接。我连接一个不断发送和接收消息的客户端,并尝试连接第二个,但第二个总是返回一个BindException告诉我该地址已被使用。我是否将整个多线程的内容弄错了,无论是在概念上还是在我的代码中?

我的服务器:

ServerSocket serverSocketUPMS1 = null;
    try {
        serverSocketUPMS1 = new ServerSocket(Integer.parseInt(cfg.getProperty("UPMSServerPort")));
        serverSocketUPMS1.setSoTimeout(0);
        log.info("Starting the USSDInterface server at port "+serverSocketUPMS1.getLocalPort());
    } catch (IOException e) {
        log.error("The TCP server couldn't be started",e);
        finish = true;
    }

    while (!finish) {
            try {
                log.info("Waiting for a socket to connect...");
                Socket subscriberSocket = serverSocketUPMS1.accept();
                //Timeout de sesion ussd para poder crear una TimeoutException
                int timeOutSocket = Integer.parseInt(cfg.getProperty("USSDSocketTimeout"));
                log.info("New client arrived from " + subscriberSocket.getRemoteSocketAddress());

                upms = new USSDSocket2(subscriberSocket,timeOutSocket);
                Thread t1 = new Thread(upms);
                t1.setName(Integer.toString(subscriberSocket.getLocalPort()) +","+ subscriberSocket.getRemoteSocketAddress() +", upms");
                t1.start();
                UPMSSimUtils.createAvailableInstance(upms);
                log.trace("USSD Socket created and initiated");
            }
            catch (Exception e) {
                log.warn("There's been an error while working with the server socket"+e.getMessage(), e);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e1) {
                    log.warn("There's been an error while waiting to resume the socket listenting"+e1.getMessage(), e1);
                }
            }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            log.warn("There's been an error while waiting in the server"+e.getMessage(), e);
        }
    }

    try {
        serverSocketUPMS1.close();
        log.info("TCP Server is now DOWN");
    } catch (IOException e) {
        log.error("There was an error while closing the server socket. TCP Server is now DOWN",e);
    }
    upms.stop();

处理线程:

public void run() {
    new Thread(new Sender()).start();
    while (!finish) {
        byte buffer[] = new byte[10000];
        byte size[] = new byte[4];
        try {
            this.socket.getInputStream().read(size, 0, 4);
            Integer largo = calcularTamanio(size);
            log.debug("Size in bytes: "+size);
            log.debug("Length of the incoming string: " + largo);
            this.socket.getInputStream().read(buffer, 0, largo);
            log.debug("Buffer of the incoming string: " + tostr2(buffer));
            decodeMessage(parseXML(toStr(buffer)), toStr(buffer));

        } catch (SocketException e) {
            log.error("Socket exception: " + e.getMessage(), e);
            this.finish = true;
        } catch (IOException e) {
            log.error("IO exception: " + e.getMessage(), e);
            this.finish = true;
        } catch (JDOMException e) {
            log.error("JDOM exception: " + e.getMessage(), e);
        } catch (Exception e) {
            log.error("Unknown exception: " + e.getMessage(), e);
            this.finish = true;
        }
        // try {
        // Thread.sleep(1);
        // } catch (InterruptedException e) {
        // log.error(e.getMessage(), e);
        // }
    }
    try {
        this.socket.close();
        this.socketUDP.close();
    } catch (IOException e) {
        log.error("Error closing the sockets at the USSDSocket", e);
    }
}

创建客户端套接字:

try{
                socketsCreated++;
                log.info("Attempting to create a socket");
                Properties properties=Config.getInstance().getCfg();

                ussdIface = new USSDInterfaceServerClass(properties);

                int port=Integer.parseInt(properties.getProperty("TestClientSocketTargetPort"));

                log.info("Client will connect to "+properties.getProperty("TestClientSocketTargetAddress")+":"+port);

                clientSocket = new Socket(properties.getProperty("TestClientSocketTargetAddress"),port);
                log.info("Socket connected");
                log.info("Client socket targeting "+properties.getProperty("TestClientSocketTargetAddress")+":"+port+" created");

                USSDSocket2 ussdSocket=new USSDSocket2(clientSocket,Integer.parseInt(properties.getProperty("USSDSocketTimeout")));
                UPMSSimUtils.createAvailableInstance(ussdSocket);

                upms = UPMSSimUtils.getAvailable(properties);

                Thread t1 = new Thread(ussdSocket);
                t1.setName("ussdsocket client test");
                t1.start();

                log.info("USSDSocket setted on the UPMSSimUtils");

                USSDSocketClientThread socketClientThread=instance.new USSDSocketClientThread(upms, "ClientSocketThread-"+socketsCreated);
                openSockets.add(socketClientThread);
                new Thread(socketClientThread).start();

                Thread.sleep(waitTimeBetweenConnections);
            }catch(Throwable throwable){
                log.warn("Error with a new connection",throwable);
                socketsCreated--;
            }

通过套接字发送数据的唯一功能:

public void send(String message) throws IOException {
    log.info("Trying to send message "+message);
    if (message != null && !"".equals(message)) {
        int largo = message.length();
        // largo = 800;
        byte largobytes[] = new byte[4];
        largobytes[0] = (byte) (largo % 256);
        largobytes[1] = (byte) (largo / 256);
        largobytes[2] = (byte) (largo & 0x00FF0000);
        largobytes[3] = 0;
        this.socket.getOutputStream().write(largobytes);
        log.trace("Byte length sent: "+largobytes);
        this.socket.getOutputStream().write(message.getBytes());
        log.info("Message sent successfully");
    }
}

处理线程负责读取通过套接字发送的所有内容。然后,decodeMessage创建一个响应,该响应在处理后通过同一个套接字发送。一个不同的实用类允许我通过引用它来发送消息,并引用它并等待它的响应。

我不知道它是否是我从输入/输出流中读取的方式或者是什么(使用普通流绑定或阻塞套接字?),但它确实如此令人烦恼的是,每一个例子似乎都告诉我,当它给我带来那些错误时,我所做的就是好的。

1 个答案:

答案 0 :(得分:0)

忘掉一切。错误是代码的原始制造者在硬编码端口上启动了硬编码套接字。由于套接字没有被使用,我从未注意到它的存在(我错误地认为错误的堆栈跟踪导致实际工作套接字,但事实并非如此)