客户端服务器多线程Socket

时间:2017-05-11 19:16:40

标签: java eclipse multithreading sockets

我正在开发一个带有Socket的软件,与服务器建立连接(我在那里安装了PgAdmin for DB)。 我创建客户端e服务器代码并且它们运行良好但我不知道如何在用户执行某些操作时通过套接字发送数据。该软件就像一个社交网络,用户登录并查看其他用户记录的信息和新闻。

public class LoginForm {

private JTextField EditUsername;
private JTextField EditEmail;

private static Client client;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                client = new Client();
                client.connectToServer();
                LoginForm window = new LoginForm();                 
                window.Loginframe.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public LoginForm() {
    initialize();
}
...
...
String username = "USER"; client.SendToServer(username );   

这是我的登录表单,首先将客户端连接到服务器。然后,当我需要向服务器发送信息时,我不知道我需要做什么!!!

    import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;


public class Client {

private BufferedReader in;
private PrintWriter out;

private static Socket socket;
private static String number ="0" ;


/**
 * Constructs the client by laying out the GUI and registering a
 * listener with the textfield so that pressing Enter in the
 * listener sends the textfield contents to the server.
 */
public Client() {   
}

public void connectToServer() throws IOException {

    String host = "localhost";
    int port = 4000;
    InetAddress address;
    try {
        address = InetAddress.getByName(host);

        socket = new Socket(address, port);

        //Send the message to the server
        OutputStream os = socket.getOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(os);
        BufferedWriter bw = new BufferedWriter(osw);

        String number = "1";

        String sendMessage = number;
        bw.write(sendMessage);
        bw.flush();
        System.out.println("Message sent to the server : "+sendMessage);

        //Get the return message from the server
        InputStream is = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);

        }
    catch (Exception exception)
    {
        exception.printStackTrace();
    }
    finally
    {
        //Closing the socket
        try
        {
            socket.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
 public void SendToServer(String username){

 }
}

所以这是接收字符串User但我需要做什么的客户端???创建另一个socket连接? 请帮助我,插座让我发疯。 我必须用户套接字(我知道RMI要好得多)

1 个答案:

答案 0 :(得分:3)

答案非常简短:您需要在private static Socket socket;方法中设置private BufferedReader in;private PrintWriter out;connectToServer()个局部变量。此外,您的主要方法中还有private static Client client;

更长的回答:

  

客户端服务器多线程套接字

这有点值得商榷,因为没有像“多线程套接字”那样,你要么拥有“多线程服务器”或“单线程服务器”,这基本上意味着你的服务器能够处理/处理并发连接或它不会。

现在,假设在服务器端你只有Socket clientSocket = serverSocket.accept();然后你总是在clientSocket对象上读写,那么你就有了“单线程服务器”,这基本上意味着直到第一个请求不是完成后,您的第二个请求将保留在队列中。如果你想创建一个“多线程服务器”,那么你每次都会创建一个新的线程然后进行处理,这里基本上你会有一个代表唯一客户端连接的新套接字。下面是一个示例“多线程服务器”代码。

现在,来到客户端,您将指定您的服务器套接字详细信息,以及{JER} socket = new Socket(address, port);的方式,所以基本上会在您的“客户端”使用您的一些随机端口号打开一个新的套接字结束(请注意,这不是随机服务器端口号,在您的最终JVM将从OS获取随机“可用”端口号进行通信),该套接字对象将代表与服务器的唯一连接。那么,您将访问该套接字上的输出流(将数据发送到服务器)和输入流(以从服务器读取数据)。

现在,这是您的案例 - 在客户端,您可以保持该套接字打开并将其用于所有服务器通信,例如用户单击一次,使用该套接字进行通信,然后再次将其用于下一个点击等(请注意我只是想解释一下),或者只要你想要进行通信,你就会在你的最后创建一个新的套接字并进行沟通。现在,通常用户点击GUI将联系在新线程中请求的服务器和服务器进程,因此您的服务器(您希望从服务器进行通信的服务器)通信代码将在新线程中运行,并在您的connectToServer()中的案例代码,只需要确保每次在服务器端创建一个新套接字而不是使其静态并为每个请求重用相同的套接字。

现在,这是您正在做的原始案例,如果您使用Spring或其他一些框架/ API,那么您可以免费获得连接池。

  

所以这是接收字符串User但我需要的客户端   做???创建另一个套接字连接?

是的,你应该每次创建一个新的客户端套接字并使用它,无论是隐式还是通过创建一个新的线程进行通信,我已经在上面解释了你的情况;并且重点是每次你应该在你的服务器上有一个新的套接字用于与服务器通信。

  

请帮助我,插座让我发疯。

不要担心只是理解基本,你会没事的。最好是阅读this或完成trail本身。

  

我必须用户套接字(我知道RMI要好得多)

你无法比较这样,最终无论是RMI,CORBA,RPC等等,客户端都会有一个套接字,服务器端会有一个套接字。以防万一 - 服务器端套接字+客户端套接字=服务器和客户端之间的唯一连接。

相同的“多线程服务器”代码:

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;

import com.learn.Person;

/**
 * @author himanshu.agrawal
 *
 */
public class TestWebServer2 {

    public static void main(String[] args) throws IOException {
        startWebServer();
    }


    /**
     * test "backlog" in ServerSocket constructor
test -- If <i>bindAddr</i> is null, it will default accepting
     * connections on any/all local addresses.
     * @throws IOException
     */

    private static void startWebServer() throws IOException {
        InetAddress address = InetAddress.getByName("localhost");
        ServerSocket serverSocket = new ServerSocket(8001, 1, address);
        // if set it to 1000 (1 sec.) then after 1 second porgram will exit with SocketTimeoutException because server socket will only listen for 1 second.
        // 0 means infinite
        serverSocket.setSoTimeout(/*1*/0000);

        while(true){
            /*Socket clientSocket = serverSocket.accept();*/ // a "blocking" call which waits until a connection is requested
            System.out.println("1");
            TestWebServer2.SocketThread socketThread = new TestWebServer2().new SocketThread();
            try {
                socketThread.setClientSocket(serverSocket.accept());
                Thread thread = new Thread(socketThread);
                thread.start();
                System.out.println("2");
            } catch (SocketTimeoutException socketTimeoutException) {
                System.err.println(socketTimeoutException);
            }
        }

    }

    public class SocketThread implements Runnable{

        Socket clientSocket;

        public void setClientSocket(Socket clientSocket) throws SocketException {
            this.clientSocket = clientSocket;
            //this.clientSocket.setSoTimeout(2000); // this will set timeout for reading from client socket.
        }

        public void run(){
            System.out.println("####### New client session started." + clientSocket.hashCode() + " | clientSocket.getLocalPort(): " + clientSocket.getLocalPort()
                    + " | clientSocket.getPort(): " + clientSocket.getPort());
            try {
                listenToSocket(); // create this method and you implement what you want to do with the connection.
            } catch (IOException e) {
                System.err.println("#### EXCEPTION.");
                e.printStackTrace();
            }
        }


    }

}