Почему в этом примере TCP-сервер генерирует исключения, если он не закрыт? - PullRequest
0 голосов
/ 02 июня 2011

Это написано в Groovy, кстати

Некоторое время я не испортил свой сценарий TCP-сервера и решил, что я хочу, чтобы он оставался открытым и продолжал слушать даже после его использования, а не только для одного использования. Однако, когда я делаю это, он генерирует исключение, а затем закрывает скрипт в любом случае.

Мой пример сценария выглядит следующим образом:

TCP-сервер

def server = new ServerSocket(2000)

println("Waiting for connection")


    server.accept() { socket ->
        socket.withStreams { input, output ->

        w = new BufferedWriter(new OutputStreamWriter(output))
        String message = "Connection was successful"

            r = new BufferedReader(new InputStreamReader(input))

        while(true) {
        if(message !=null) {
            sendMessage(message)
            message = null
        }

        String a = r.readLine()

        if(a.equals("name"))
            message = "Bob"
        else if(a.equals("date"))
            message = new Date()
        else if(a.equals("ip")) 
            message = InetAddress.getLocalHost().getHostAddress()
        else if(a.equals("quit")) {
            server.close()
            return
        } else 
            message = "$a command unknown"
        }
        }
    }

def sendMessage(String msg) {
    println("Sending: >" + msg + "<")
    w.writeLine(msg)
    w.flush();
}

Проблема возникает у клиента. Если я использую команду quit, то она закрывает сервер после выполнения других команд. Однако, если я удаляю quit из команд, то сервер пытается остаться открытым, выдает исключение и в любом случае закрывает сервер.

TCP-клиент

def commands 
def answers
def requestSocket
def r
def w

String host = "filipekdt7"
commands = ["name",
        "date",
        "ip",
        "quit"]   //If I take out "quit" then the exceptions get thrown, but I want to leave my server script running

answers = [commands.size]

requestSocket = new Socket(host, 2000)

r = new BufferedReader(new InputStreamReader(requestSocket.getInputStream()))
w = new BufferedWriter(new OutputStreamWriter(requestSocket.getOutputStream()))

String message = r.readLine()
println "Server >" + message

for(int n = 0; n < commands.size; n++) {
    sendMessage(commands[n],w)
    answers[n] = r.readLine()
}

w.flush()
w.close()


public String sendMessage(def msg, def w) {
    w.write(msg+"\r\n")
    w.flush()
    println "Client>" + msg
}

Кто-нибудь знает, как сохранить сценарий сервера? Я думаю, что просто смотрю на что-то простое.

1 Ответ

2 голосов
/ 02 июня 2011

Попробуйте изменить код своего сервера следующим образом:

def server = new ServerSocket(2000)
println("Waiting for connection")

while (true) {
    server.accept() { socket ->
        socket.withStreams { input, output ->
            def w = new BufferedWriter(new OutputStreamWriter(output))
            String message = "Connection was successful"
            def r = new BufferedReader(new InputStreamReader(input))

            while (true) {
                if (message !=null) {
                    sendMessage(message, w)
                    message = null
                }

                String a = r.readLine()
                if (a == null) {
                    socket.close()
                    println "Client disconnected"
                    return
                } else if (a.equals("name")) {
                    message = "Bob"
                } else if (a.equals("date")) {
                    message = new Date()
                } else if (a.equals("ip")) {
                    message = InetAddress.getLocalHost().getHostAddress()
                } else if (a.equals("quit")) {
                    server.close()
                    return
                } else { 
                    message = "$a command unknown"
                }
            }
        }
    }
}

def sendMessage(msg, writer) {
    println("Sending: >" + msg + "<")
    writer.writeLine(msg.toString())
    writer.flush();
}

Обратите внимание, как ServerSocket многократно accept s-соединений в цикле while. Это поддерживает работу серверного скрипта.

Вы получили исключение ранее, потому что пытались отправить сообщение клиенту, который отключился от сервера. Чтобы это исправить, вы должны убедиться, что команда, прочитанная с клиента, действительна (т.е. a != null), прежде чем пытаться отправить ответ обратно.

...