java套接字问题连接被对等方重置

标签 java sockets

我正在大学的一个项目中工作,我需要创建一个带有套接字的服务器客户端应用程序,现在我只需要发送一个对象抛出,但我遇到了一些问题。如果有人指出,这对我会非常有帮助我知道如何解决这个错误,我尝试了很多方法并在网上查找了很多,但是发现了一些有用的东西,抱歉英语不好,提前感谢这是我遇到的异常(exception)。

服务器输出

Server started--1
Server started
new connection , all conections are :1
Starting thread for client 1 at Thu Mar 29 14:32:48 CEST 2018
Client 1's host name is 127.0.0.1
Client 1's IP Address is 127.0.0.1
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1877)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1786)
at java.io.ObjectOutputStream.<init>(ObjectOutputStream.java:247)
at Server$HandleClient.run(Server.java:61)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

服务器代码

import java.io.*;
import java.net.*;
import java.util.Date;
import java.util.concurrent.*;

public class Server {

private ExecutorService executor = Executors.newCachedThreadPool();
private int connectedDevices=0;
private int portNr =8090;
private boolean running=true;
private int clientNo=0;

public Server(){
    new Thread(()->{
        try{
            System.out.println("Server started--1");
            ServerSocket serverSocket = new ServerSocket(portNr);
            System.out.println("Server started");

            while(running){
                Socket socket = serverSocket.accept();
                clientNo++;
                connectedDevices++;
                System.out.println("new connection , all conections are :"+connectedDevices);
                System.out.println("Starting thread for client " + clientNo +" at " + new Date() );
                InetAddress inetAddress = socket.getInetAddress();
                System.out.println("Client " + clientNo + "'s host name is "+ inetAddress.getHostName() );
                System.out.println("Client " + clientNo + "'s IP Address is "+ inetAddress.getHostAddress() );
                executor.execute(new HandleClient(socket));
            }

        }catch(Exception e){
            e.printStackTrace();

        }    
    }).start();
}

public synchronized void decrement(){
    connectedDevices--;
    System.out.println("lost connection , all conections are :"+connectedDevices);
}

public static void main(String [] args){    
    Server s=new Server();
}


class HandleClient implements Runnable{
private Socket socket;

public HandleClient(Socket socket){
    this.socket=socket;
}


public void run() {
    try{
        ObjectOutputStream dos = new ObjectOutputStream(socket.getOutputStream());
        ObjectInputStream din = new ObjectInputStream(socket.getInputStream());
        String msg="";

            System.out.println(msg);
            Date date = (Date) din.readObject();
            System.out.println("(Client) Current time is:          " + new Date() );
            System.out.println("(Client) Object read from server : " + date );
            decrement();

    }catch(Exception e){
        e.printStackTrace();
    }
}

}
}

最后是客户端代码

import java.io.*;
import java.net.*;
import java.util.Date;

public class Client {
public static void main(String[] args)  {
    try {
        System.out.println("before socket");
        Socket s = new Socket("localhost",8090);
        System.out.println("after socket");
        ObjectOutputStream dos = new ObjectOutputStream(s.getOutputStream());
        System.out.println("before sending");
        dos.writeObject(new Date());
        System.out.println("after sending");
    }catch(IOException e) {
        e.printStackTrace();
    }
}
}

最佳答案

为什么你认为你的程序有问题。它正在按预期工作。

但是,值得注意的是你的代码,我相信你希望客户端和服务器无限期地运行。

但是无限循环在哪里? 你没有。因此,客户端将写入一个 Date 对象,服务器将读取它。仅一次。

为了保持连续性,我采用了您的代码,添加了两个无限循环,它可以工作。


import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    private ExecutorService executor = Executors.newCachedThreadPool();
    private int connectedDevices = 0;
    private int portNr = 8090;
    private boolean running = true;
    private int clientNo = 0;
    private ServerSocket serverSocket;

    public Server() {
        new Thread(() -> {
            try {
                System.out.println("Server started--1");
                serverSocket = new ServerSocket(portNr);
                System.out.println("Server started");

                while (running) {
                    Socket socket = serverSocket.accept();
                    clientNo++;
                    connectedDevices++;
                    System.out.println("new connection , all conections are :" + connectedDevices);
                    System.out.println("Starting thread for client " + clientNo + " at " + new Date());
                    InetAddress inetAddress = socket.getInetAddress();
                    System.out.println("Client " + clientNo + "'s host name is " + inetAddress.getHostName());
                    System.out.println("Client " + clientNo + "'s IP Address is " + inetAddress.getHostAddress());
                    executor.execute(new HandleClient(socket));
                }

            } catch (Exception e) {
                e.printStackTrace();

            }
        }).start();
    }

    public synchronized void decrement() {
        connectedDevices--;
        System.out.println("lost connection , all conections are :" + connectedDevices);
    }

    public static void main(String[] args) {
        new Server();
    }

    class HandleClient implements Runnable {
        private Socket socket;
        private ObjectInputStream din;

        public HandleClient(Socket socket) {
            this.socket = socket;
        }

        public void run() {
            try {

                din = new ObjectInputStream(socket.getInputStream());
                String msg = "";
                while (true) {
                    System.out.println(msg);
                    Date date = (Date) din.readObject();
                    System.out.println("(Client) Current time is:          " + new Date());
                    System.out.println("(Client) Object read from server : " + date);
                    decrement();
                    Thread.sleep(1000);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}

客户:

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Date;

public class Client {
    private static Socket s;

    public static void main(String[] args) throws InterruptedException {
        try {

            System.out.println("before socket");
            s = new Socket("localhost", 8090);
            System.out.println("after socket");
            ObjectOutputStream dos = new ObjectOutputStream(s.getOutputStream());
            while (true) {
                System.out.println("before sending");
                dos.writeObject(new Date());
                System.out.println("after sending");
                Thread.sleep(1000);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

关于java套接字问题连接被对等方重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49556431/

相关文章:

java - 如何按值从 HashMap 中删除条目?

java - 用于匹配注释字段上的公共(public)方法调用的 Aspectj 切入点

c - 通过选择等待数据不起作用

java - Java 中的字节 0xFF (11111111) 发生了什么?

java - 参数太少的 ObjectDB Select 查询

java - 如何通过 TCP 连接发送类?

c# - 为什么在20%繁忙的计算机上出现IPC延迟

c++ - recv 函数在使用两次时失败

c - UDP -- 套接字 - 绑定(bind)错误 - 地址已被使用?

java - 即使未调用默认构造函数,显式构造函数仍然具有默认值。