线程“主”java.net.SocketException 中的异常:连接重置 -

Posted

技术标签:

【中文标题】线程“主”java.net.SocketException 中的异常:连接重置 -【英文标题】:Exception in thread "main" java.net.SocketException: Connection reset - 【发布时间】:2015-02-01 16:21:33 【问题描述】:

我创建了一个简单的客户端/服务器程序,客户端从命令行参数获取文件。然后客户端将文件发送到服务器,在服务器上使用 GZIP 压缩并发送回客户端。

服务器程序第一次运行时很好,没有产生错误,但运行客户端后出现错误。

我收到一条错误消息,提示连接已重置,我尝试了许多不同的端口,所以我想知道我的代码或关闭流的时间是否有问题?

任何帮助将不胜感激!

编辑 - 对两个程序进行了更改。

客户:

import java.io.*;
import java.net.*;

//JZip Client

public class NetZip 

    //Declaring private variables.
    private Socket socket = null;
    private static String fileName = null;
    private File file = null;
    private File newFile = null;
    private DataInputStream fileIn = null;
    private DataInputStream dataIn = null;
    private DataOutputStream dataOut = null;
    private DataOutputStream fileOut = null;


    public static void main(String[] args) throws IOException 
    try 
        fileName = args[0];
        
    catch (ArrayIndexOutOfBoundsException error) 
        System.out.println("Please Enter a Filename!");
    
    NetZip x = new NetZip();
    x.toServer();
    x.fromServer();

    

    public void toServer() throws IOException
    while (true)
    //Creating socket
       socket = new Socket("localhost", 4567);
       file = new File(fileName);

       //Creating stream to read from file.
       fileIn = new DataInputStream(
           new BufferedInputStream(
               new FileInputStream(
                   file)));

       //Creating stream to write to socket.
       dataOut = new DataOutputStream(
           new BufferedOutputStream(
               socket.getOutputStream()));

       byte[] buffer = new byte[1024];

           int len;
           //While there is data to be read, write to socket.
        while((len = fileIn.read(buffer)) != -1)
            try
            System.out.println("Attempting to Write " + file
                + "to server.");
            dataOut.write(buffer, 0, len);
            
            catch(IOException e)
            System.out.println("Cannot Write File!");
            
            
        fileIn.close();
        dataOut.flush();
        dataOut.close();

        

    
  //Read data from the serversocket, and write to new .gz file.
    public void fromServer() throws IOException

    dataIn = new DataInputStream(
           new BufferedInputStream(
                   socket.getInputStream()));

    fileOut = new DataOutputStream(
           new BufferedOutputStream(
               new FileOutputStream(
                   newFile)));

    byte[] buffer = new byte[1024];

        int len;
        while((len = dataIn.read(buffer)) != -1)
            try 
            System.out.println("Attempting to retrieve file..");
            fileOut.write(buffer, 0, len);
            newFile = new File(file +".gz");

            
            catch (IOException e )
            System.out.println("Cannot Recieve File");
            
         
        dataIn.close();
        fileOut.flush();
        fileOut.close();
        socket.close();

    



服务器:

import java.io.*;
import java.net.*;
import java.util.zip.GZIPOutputStream;

//JZip Server

public class ZipServer 

    private ServerSocket serverSock = null;
    private Socket socket = null;
    private DataOutputStream zipOut = null;
    private DataInputStream dataIn = null;

    public void zipOut() throws IOException 

    //Creating server socket, and accepting from other sockets.
    try
    serverSock = new ServerSocket(4567);
    socket = serverSock.accept();
    
    catch(IOException error)
        System.out.println("Error! Cannot create socket on port");
    

    //Reading Data from socket
    dataIn = new DataInputStream(
           new BufferedInputStream(
                   socket.getInputStream()));

    //Creating output stream.
    zipOut= new DataOutputStream(
        new BufferedOutputStream(
            new GZIPOutputStream(
                socket.getOutputStream())));

    byte[] buffer = new byte[1024];

        int len;
        //While there is data to be read, write to socket.
        while((len = dataIn.read(buffer)) != -1)
            System.out.println("Attempting to Compress " + dataIn
                + "and send to client");
            zipOut.write(buffer, 0, len);
         
        dataIn.close();
        zipOut.flush();
        zipOut.close(); 
        serverSock.close();
        socket.close();
    

    public static void main(String[] args) throws IOException
    ZipServer run = new ZipServer();
    run.zipOut();

    


错误信息:

Exception in thread "main" java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
    at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
    at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
    at java.io.DataInputStream.read(DataInputStream.java:100)
    at ZipServer.<init>(ZipServer.java:38)
    at ZipServer.main(ZipServer.java:49)

【问题讨论】:

您不需要 while(true) 方法中的 toServer() 循环。在close() 之前,您不需要DataOutputStreamDataInputStream. flush() 是多余的。 @EJP 谢谢,我已经摆脱了所有的刷新和数据流。但是它似乎仍然不起作用?值得一提的是我正在运行 Ubuntu 并使用 Eclipse。我没有编译器错误或警告标志,错误是一样的。在错误的底部它说;在 ZipServer.zipOut(ZipServer.java:38) 在 ZipServer.main(ZipServer.java:53) 指向; while((len = dataIn.read(buffer)) != -1) 和 run.zipOut(); (在 main 方法中)会不会和这些有关? 那些评论是cmets,而不是答案。并且不要仅仅因为您第一次没有得到答案而重新发布问题。 抱歉,我没有意识到我已经转发了。在尝试回复评论时,我不小心按了 Enter 而不是 shift+enter。可能是因为我在多个选项卡中打开了页面。 @EJP 【参考方案1】:

首先,发生错误是因为客户端失败并在发送任何数据之前结束,因此 连接在服务器要读取时关闭。 发生错误是因为您将 File 对象分配给未使用的局部变量(您的编译器没有警告吗?)

public File file = null;
public File newFile = null;

public static void main(String[] args) throws IOException 
try 
    String fileName = args[0];
    File file = new File(fileName);
    File newFile = new File(file +".gz");
     
catch (ArrayIndexOutOfBoundsException error) 
    System.out.println("Please Enter a Filename!");

但是在您的 toServer 方法中,您使用类变量文件作为 FileInputStream 的参数,并且此变量为空,这会导致程序结束的错误。

其次,如果你完成了对输出流的写入,你应该调用

socket.shtdownOutput();

否则,服务器会尝试读取,直到发生超时。

【讨论】:

好的,在你编辑之后,我的答案的第一部分已经过时了:) 如果他正在关闭套接字,他不需要调用shutdownOutput(),并且不会发生超时,因为他没有设置。 @EJP 关闭套接字能解决问题吗?我不确定是否应该关闭连接,因为服务器必须继续监听客户端。我遇到了同样的问题,我的服务器很简单,它接受客户端应用程序并返回调用一个向客户端返回强消息的方法,因此通信工作正常。不过,一件奇怪的事情是,如果我关闭客户端,服务器也会死机并出现连接重置错误。我的服务器有一个持续监听客户端连接的 while 循环,如果发生任何连接,它会返回字符串 实际上并没有解决问题。我仍然有同样的错误。【参考方案2】:

问题是服务器无法下载 apache maven

所以你可以做的就是复制 apache maven 文件夹并将其粘贴到项目内的 wrapper 文件夹中。

会手动下载apache maven,肯定能用。

【讨论】:

以上是关于线程“主”java.net.SocketException 中的异常:连接重置 -的主要内容,如果未能解决你的问题,请参考以下文章

Android 异步操作Android 线程切换 ( 判定当前线程是否是主线程 | 子线程中执行主线程方法 | 主线程中执行子线程方法 )

子线程怎么不阻塞主线程

QT中UI主窗口如何与子线程相互传递参数

java 子线程 回调 主线程

C++怎么在主线程中使用子线程的数据? 比如说主线程中有一个数组,如何在子线程中调用这个数组

EventBus事件通信框架 ( 发送事件 | 判断发布线程是否是主线程 | 子线程切换主线程 | 主线程切换子线程 )