再次重用j​​ava套接字客户端

use*_*840 5 java sockets

我的问题很简单.我只想再次使用客户端对象套接字.

通常,只要客户端尝试连接服务器,人们就会创建一个新的套接字:

 Socket test = new Socket (host, port);
 OutputStream out = test.getOutputStream ();
 InputStream in = test.getInputStream ();
 out.writeObject (object)
 out.flush ();
 in.readObject();
Run Code Online (Sandbox Code Playgroud)

在第一个writeObject之后,我想再次通过重用out.writeObject(nextObject)向服务器发送更多信息,但是不再访问服务器.为了使它工作,我必须完成上述所有步骤.为什么?


这是我用来测试我的意思的代码."Second Request not not ..."之后的代码无法到达服务器.但是,如果我删除那些评论之上的评论,它将会通过.为什么我不能重新使用相同的客户端套接字对象而不必使用新的Socket().

Class Hello -> Data passed between the server and the client
Class TestClient -> Client
Class TestServer -> Server


package tests;

import java.io.Serializable;


public class Hello implements Serializable {

    String hola = "hello my friend";

    public String getHello () {

        return hola;

    }

    public void setHello (String str) {

        hola = str;

    }

}


package tests;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TestClient {

    public static void main(String[] args) {


        try {

            ObjectOutputStream clientOutput;
            ObjectInputStream serverInput;
            Hello goingout = new Hello ();

            Socket client = new Socket ("localhost", 5555);
            clientOutput  = new ObjectOutputStream (client.getOutputStream());
            serverInput   = new ObjectInputStream (client.getInputStream());

            clientOutput.writeObject(goingout);
            clientOutput.flush();
            Hello comingin = (Hello) serverInput.readObject();
            System.out.println ("first time received: " + comingin.getHello());


            /*
             * Socket client = new Socket ("localhost", 5555);
               clientOutput  = new ObjectOutputStream (client.getOutputStream());
               serverInput   = new ObjectInputStream (client.getInputStream());
             */

            /*
             * Second request doesn't got through the server
             */
            comingin.setHello("again");
            clientOutput.writeObject(goingout);
            clientOutput.flush();
            comingin = (Hello) serverInput.readObject();
            System.out.println ("second time received: " + comingin.getHello());



        } catch (ClassNotFoundException ex) {
            System.out.println (ex.getMessage());
        } catch (UnknownHostException ex) {
            System.out.println (ex.getMessage());
        } catch (IOException ex) {
            System.out.println (ex.getMessage());
        }


    }

}

public class TestServer {

    public static void main(String[] args) {



        try {

              ServerSocket server = new ServerSocket(5555, 100);
              ObjectInputStream clientInput;
              ObjectOutputStream serverOutput;

              for (;;) {
                  System.out.println ("Listening for connections");
                  Socket fromClient = server.accept();
                  serverOutput = new ObjectOutputStream (fromClient.getOutputStream());
                  clientInput = new ObjectInputStream (fromClient.getInputStream());
                  Hello received = (Hello) clientInput.readObject();
                  serverOutput.writeObject(received);
                  serverOutput.flush();
              }


        } catch (ClassNotFoundException ex) {
            Logger.getLogger(TestServer.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(TestServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

aoi*_*222 2

问题在于服务器上的声明Socket fromClient = server.accept();位于循环范围内for。因此,在循环结束时for(after serverOutput.flush();),fromClient变量被销毁,并在下次循环开始时创建一个新变量。如果您希望同一连接能够发送/接收多条消息,则需要像这样重构它:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap

public class User extends Runnable
{
    public String username;
    public Socket socket;
    public TestServer testServerReference;
    ObjectInputStream clientInput;
    ObjectOutputStream serverOutput;

    public User(Socket s, TestServer tS)
    {
        socket = s;
        testServerReference = tS;
    }

    /**
     *  Creates the in/out Streams, returns the username
     */
    public String init()
    {
        serverOutput = new ObjectOutputStream (fromClient.getOutputStream());
        clientInput = new ObjectInputStream (fromClient.getInputStream());
        this.username = (String)clientInput.readObject();  //the first thing the client should send is a username

    }

    public void run()
    {
        try
        {
            //add send/receive logic here for connected client
        }
        catch (Exception ex)
        {
        }
        finally
        {
            testServerReference.removeUser(username);
        }
    }
}

public class TestServer {

    public static HashMap<String,User> userList = new HashMap<String,User>();
    public static void main(String[] args) 
    {

        try {

              ServerSocket server = new ServerSocket(5555, 100);

              while (true) //start accepting new connections
              {
                  System.out.println ("Listening for connections");
                  Socket fromClient = server.accept();
                  User newUser = new User(fromClient,this);
                  String newUsername = newUser.init();
                  userList.add(newUsername,newUser);
                  (new Thread(newUser)).start();
              }


        } catch (ClassNotFoundException ex) {
            Logger.getLogger(TestServer.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(TestServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void removeUser(String username)
    {
        userList.remove(username);
    }

}
Run Code Online (Sandbox Code Playgroud)

我只是很快地将这段代码放在一起,还没有测试编译它,所以它可能仍然包含一些错误,但总体思路是存在的。