java - 客户端服务器多线程Socket

标签 java eclipse multithreading sockets

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

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 的客户端,但我需要做什么???创建另一个套接字连接? 请帮助我,套接字让我发疯。 我必须使用套接字(我知道 RMI 更好)

最佳答案

非常简短的答案:您需要创建private static Socket socket;private BufferedReader in;private PrintWriter out; connectToServer() 方法内的 局部变量。另外,private static Client client; 在你的 main 方法中。

更长的答案:

Client server multithread Socket

这有点值得商榷,因为没有什么像“多线程套接字”这样的东西,您将拥有“多线程服务器”或“单线程服务器”,这基本上意味着您的服务器能够处理/处理并发连接,否则就不会。

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

现在,在客户端,您将指定服务器套接字详细信息,就像您执行的方式 socket = new Socket(address, port); 一样,因此基本上会在以下位置打开一个新套接字你的“客户端”在你的末端使用一些随机端口号(请注意,这不是一个随机的服务器端口号,在你的末端JVM将从操作系统获得一个随机的“可用”端口号进行通信),并且该套接字对象将代表与服务器的唯一连接。因此,您将访问该套接字上的输出流(将数据发送到服务器)和输入流(从服务器读取数据)。

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

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

So this is the client that receive the string User but What I need to do ??? create another socket connection ?

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

Please help me, sockets are driving me mad.

别担心,只要了解基本的知识就可以了。最好是阅读this或完整trail本身。

I must user socket(I know RMI is much better)

不能这样比较,到底是RMI、CORBA、RPC等等,客户端都会有一个socket,服务器端也会有一个socket。以防万一 - 服务器端套接字 + 客户端套接字 = 服务器和客户端之间的唯一连接。

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

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();
            }
        }


    }

}

关于java - 客户端服务器多线程Socket,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43923892/

相关文章:

java - 变量可能尚未初始化

Eclipse 工作区 : how to rename workspace

android - 在 Android 插件中通过 AsyncTask 使用 cordova getThreadPool.execute()

java - java中静态方法的线程安全

multithreading - POSIX命名信号量可以同步线程吗?

java - 尝试使用抽象数据类型 - 如何通过继承调用方法

java - 在 jsf 中使用 ArrayDataModel 向数据表添加一行?

python - 尝试在 Eclipse 中运行 Python 2.7 和 3.4 时遇到问题

java - Eclipse、subclipse 和 JAR 依赖项

java - Calendar.getTime IllegalArgumentException