java 保持Java套接字打开?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13727959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:48:02  来源:igfitidea点击:

keeping a java socket open?

javasocketsinputiooutput

提问by PulsePanda

i'm making a program/game that will update automatically. i have the update part down, but not the checking of the version. i would have thought that it'd be pretty easy. heres what i've done. i wrote an updater for the game, and i wrote a server. the server starts a thread every time a client/updater connects. the thread handles everything. the game updater reads a file called version.txtand that provides the version number (default 0.0.1) and sends it to the server. the server does recieve the version, and will System.out.println();if the version matches, and if i change the version, it changes the output. so that part works. but that is as far as it goes. the second part of the process is that the server then sends just a text file called NPS Game.txt(it sends anything, but txt was easy to test with) and the client replaces the old version of this file with the new one that just sent. the problem is that i keep getting an error that says the Socket is closed. i've tried using socket.setKeepAlive(true);but that didnt change anything (i put that on both the client and the server). here is the code:

我正在制作一个会自动更新的程序/游戏。我有更新部分,但没有检查版本。我会认为这会很容易。继承人我所做的。我为游戏写了一个更新程序,我写了一个服务器。每次客户端/更新程序连接时,服务器都会启动一个线程。线程处理一切。游戏更新程序读取一个名为version.txt并提供版本号(默认为 0.0.1)的文件并将其发送到服务器。服务器确实收到版本,System.out.println();如果版本匹配,并且如果我更改版本,它会更改输出。所以那部分工作。但就目前的情况而言。该过程的第二部分是服务器然后只发送一个名为的文本文件NPS Game.txt(它会发送任何东西,但 txt 很容易测试)并且客户端用刚刚发送的新文件替换该文件的旧版本。问题是我不断收到一个错误,说 Socket 已关闭。我试过使用,socket.setKeepAlive(true);但没有改变任何东西(我把它放在客户端和服务器上)。这是代码:

server:

服务器:

package main;

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

import javax.swing.JOptionPane;

public class Server {
static ServerSocket serverSocket = null;
static Socket clientSocket = null;
static boolean listening = true;

public static void main(String[] args) throws IOException {
    try {
        serverSocket = new ServerSocket(6987);
    } catch (IOException e) {
        ServerThread.showmsg("Could not use port: 6987");
        System.exit(-1);
    }

    ServerThread.showmsg("server- initialized");
    ServerThread.showmsg("server- waiting...");

    while (listening)
        new ServerThread(serverSocket.accept()).start();
}
}

server thread:

服务器线程:

package main;

import java.io.*;
import java.net.Socket;
import java.net.SocketException;

import javax.swing.JOptionPane;

public class ServerThread extends Thread {
Socket socket;
ObjectInputStream in;
ObjectOutputStream out;
String version = "0.0.1";

public ServerThread(Socket socket) {
    super("Server Thread");
    this.socket = socket;
}

public void run() {
    showmsg("server- Accepted connection : " + socket);
    getVersion();
    sendFile();
}

public void getVersion() {
    try {
        ObjectInputStream ois = new ObjectInputStream(
                socket.getInputStream());
        try {
            String s = (String) ois.readObject();
            if (s.equals(version)) {
                System.out.println("server- matched version :)");
            } else {
                System.out.println("server- didnt match version :(");
                System.exit(0);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        ois.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void sendFile() {
    // sendfile
    File myFile = new File("C:\Programming\NPS\Files\bin\NPS Game.txt");
    byte[] mybytearray = new byte[(int) myFile.length()];
    FileInputStream fis;
    try {
        fis = new FileInputStream(myFile);
        BufferedInputStream bis = new BufferedInputStream(fis);
        bis.read(mybytearray, 0, mybytearray.length);
        OutputStream os = socket.getOutputStream();
        showmsg("server- Sending...");
        os.write(mybytearray, 0, mybytearray.length);
        os.flush();
        socket.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void showmsg(String s) {
    JOptionPane.showMessageDialog(null, s);
}
}

and the client/updater:

和客户端/更新程序:

package main;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JOptionPane;

import org.omg.CORBA.portable.InputStream;

public class Connections {
String IP, port;
String message = "";
Socket socket;

public Connections(boolean server, boolean updating, String IP, String port) {
    this.IP = IP;
    this.port = port;
    try {
        socket = new Socket(IP, Integer.parseInt(port));
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    if (!server) {
        if (updating) {
            try {
                sendVersion();
                updating();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            client();
        }
    }
    if (server) {

    }
}

public void sendVersion() throws IOException {

    FileReader fileReader = new FileReader(
            "C:\Program Files\AVTECH\NPS\Files\bin\version.txt");
    BufferedReader bufferedReader = new BufferedReader(fileReader);

    String stringRead = bufferedReader.readLine();

    bufferedReader.close();

    ObjectOutputStream oos = new ObjectOutputStream(
            socket.getOutputStream());
    oos.writeObject(stringRead);
    oos.flush();
    oos.close();
}

public void updating() throws IOException {
    int filesize = 6022386; // filesize temporary hardcoded

    int bytesRead;
    int current = 0;

    showmsg("client- connected");

    // receive file
    byte[] byteArray = new byte[filesize];
    java.io.InputStream inStream = socket.getInputStream();
    FileOutputStream fileOutStream = new FileOutputStream(
            "C:\Program Files\AVTECH\NPS\Files\bin\NPS Game.txt");
    BufferedOutputStream buffOutStream = new BufferedOutputStream(
            fileOutStream);
    bytesRead = inStream.read(byteArray, 0, byteArray.length);
    current = bytesRead;

    do {
        bytesRead = inStream.read(byteArray, current,
                (byteArray.length - current));
        if (bytesRead >= 0)
            current += bytesRead;
    } while (bytesRead > -1);

    buffOutStream.write(byteArray, 0, current);
    buffOutStream.flush();
    buffOutStream.close();
    inStream.close();
    socket.close();
}

public static void showmsg(String s) {
    JOptionPane.showMessageDialog(null, s);
}
}

i dont know what's wrong with it, but it is really frusturating. if anyone can help, it would be appreciated. some things ive done: google all kinds of questions, tried implementing socket.setKeepAlive(true);. also, i thought it might be of note, in the server thread, right above the line BufferedInputStream bis = new BufferedInputStream(fis);, i put System.out.println(socket.isClosed);and it returned true. thats all i have. thanks in advance!

我不知道这有什么问题,但这真的很令人沮丧。如果有人可以提供帮助,将不胜感激。我做过的一些事情:谷歌各种问题,尝试实施socket.setKeepAlive(true);。另外,我认为这可能值得注意,在服务器线程中,就在该行的正上方BufferedInputStream bis = new BufferedInputStream(fis);,我放了System.out.println(socket.isClosed);它并返回 true。这就是我的全部。提前致谢!

回答by Martijn Courteaux

I think that closing one of both streams, closes the socket. So try to remove the ois.close()call out of your getVersion()method at the server side. Also get rid of the oos.close()call in your sendVersion()method at the client side.

我认为关闭两个流之一,关闭套接字。因此,请尝试在服务器端ois.close()从您的getVersion()方法中删除调用。还要摆脱客户端方法中的oos.close()调用sendVersion()

When you construct an ObjectOutputStream or ObjectInputStream and you are done with it, you shouldn't close that stream, because it will close the underlying stream, which is in your case the socket.

当您构造 ObjectOutputStream 或 ObjectInputStream 并完成它时,您不应该关闭该流,因为它将关闭底层流,在您的情况下是套接字。