Я хочу настроить сервер / клиент, где клиент отправляет сериализуемый объект через сокет на сервер.По какой-то причине я продолжаю получать java.net.SocketException: SocketClosed
, когда пытаюсь прочитать объект, отправленный на сервер.
Вот мой код для клиента:
class Client(address: String, port: Int) {
private val connection: Socket = Socket(address, port)
private var connected: Boolean = true
private val writer = ObjectOutputStream(connection.getOutputStream())
private val reader = ObjectInputStream(connection.getInputStream())
init {
println("Connected to server at $address on port $port")
}
fun run() {
var sent = false
while (connected) {
try {
if (!sent) {
sent = true
writer.use {
it.writeObject("Hello")
it.flush()
}
println("Sent")
} else {
println("Didn't send")
}
Thread.sleep(1000)
} catch (ex: Exception) {
ex.printStackTrace()
shutdown()
}
}
}
...
}
, а вот код для сервера:
class ClientHandler(private val client: Socket) {
private val reader = ObjectInputStream(client.getInputStream())
private val writer = ObjectOutputStream(client.getOutputStream())
private var running: Boolean = false
fun run() {
running = true
while (running) {
try {
reader.use {
val packet = it.readObject()
when (packet) {
is String -> {
println("Received packet with data: ${packet}")
}
}
}
} catch (ex: Exception) {
ex.printStackTrace()
shutdown()
}
}
}
...
}
Выходные данные на моем сервере
Server is running on port 9999
Client connected: 127.0.0.1
Received packet with data: Hello
java.net.SocketException: Socket closed
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:115)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:168)
...
Итак, похоже, что один экземпляр моего String
делает это через, но более поздние вызовы утверждают, что сокет закрыт.
Во всех других постах, которые я видел по этой проблеме, утверждается, что отправитель (клиент) рано закрывает сокет.Однако я знаю, что клиент не закрывает сокет своими собственными средствами.Если я изменю свой код клиента на:
class Client(address: String, port: Int) {
...
private val writer = connection.getOutputStream() // Regular streams
private val reader = Scanner(connection.getInputStream())
...
fun run() {
var sent = false
while (connected) {
try {
if (!sent) {
sent = true
writer.write("Hello\n".toByteArray()) // Send regular byte array
println("Sent")
} else {
println("Didn't send")
}
...
}
, а код моего сервера на:
class ClientHandler(private val client: Socket) {
private val reader = Scanner(client.getInputStream()) // Regular streams
private val writer = client.getOutputStream()
private var running: Boolean = false
fun run() {
running = true
while (running) {
try {
// Just read lines from stream
println(reader.nextLine())
}
...
}
, тогда я получу то, что ожидаю:
Server is running on port 9999
Client connected: 127.0.0.1
Hello
MyЕдинственная гипотеза состоит в том, что .readObject()
как-то закрывает соединение с сокетом, заставляя следующее readObject()
вызвать исключение.Это не имеет большого смысла для меня, хотя.Почему это случилось?