客户端服务器多线程套接字 [英] Client server multithread Socket

查看:116
本文介绍了客户端服务器多线程套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

i'm developing a software that with a Socket, sets a connection with a server(where I installed PgAdmin for DB). I create the client e server code and they run perfectly but I don't know how to send data via socket when the user do some action. The software is like a social network, where users login and see their info and news from the other users that are logged.

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

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

this is my login form where firstly connect client to server. Then when I need to send info to server I don't know what i need to do !!!

    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更好)

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. I must user socket(I know RMI is much better)

推荐答案

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

Very short answer: you need to make private static Socket socket;, private BufferedReader in; and private PrintWriter out; local variables inside connectToServer() method. Also, private static Client client; inside your main method.

更长的答案:

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

Client server multithread Socket

这有点争议,因为没有像多线程套接字"这样的东西,您将拥有多线程服务器"或单线程服务器",这基本上意味着您的服务器将能够处理/处理并发连接,否则就不会.

This is bit debatable because there is nothing like "multithreaded socket", you will either have a "multi-threaded server" or "single-threaded server", which basically means that either your server would capable of handling/processing concurrent connections or it would be not.

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

Now, suppose at server side you have just Socket clientSocket = serverSocket.accept(); and then you are always reading and writing over clientSocket object then you have "single-threaded server" which basically means that until first request is not completed, your second request would remain in queue. If you want to create a "multi-threaded server" then you will create a new thread each time and then do the processing, here basically you would have a new socket representing a unique client connection. Below is a sample "multi-threaded server" code.

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

Now, coming at client side, you will specify your server socket details, the way you are doing socket = new Socket(address, port);, so basically a new socket will be opened at your "client side" using some random port number at your end (please note that this is not a random server port number, at your end JVM will get a random "available" port number from OS for communication), and that socket object would represent a unique connection with the server. So, then you will access output stream on that socket (to send data to server) and input stream (to read data from server).

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

Now, here is the catch of your case - at client side, either you can keep that socket open and use it for all server communications, like user has clicked once, communicate using that socket, and then again use that for next click etc. (please note that I am just putting this to explain), OR whenever you want a communication you will create a new socket at your end and communicate. Now, typically a user click at GUI will contact server and server processes that request in a new thread, so your server (the one with which you want to communicate from your server) communication code will be ran in a new thread, and in your case code in connectToServer(), only thing you need to make sure that each time you are creating a new socket at your server's end and not making it static and reusing same socket for each request.

现在,这是您要做的原始情况,如果您使用Spring或其他框架/API,则可以免费获得连接池.

Now, this is the raw case you are doing, if you use Spring or some other frameworks/API then you can get connection pooling for free.

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

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

是的,您应该每次都创建一个新的客户端套接字,并通过隐式或通过创建新线程进行通信的方式使用该套接字,如上所述,您的情况如何?重点是,每次您都应该在末端使用一个新的套接字来与服务器进行通信.

Yes, you should create a new client socket each time and use that, either implicitly or by creating a new thread to do communication, I have explained above how is your case; and whole point is that each time you should have a new socket at your end for communicating with server.

请帮助我,套接字使我发疯.

Please help me, sockets are driving me mad.

不用担心,只要了解基本知识即可.最好是阅读或完整的

Don't worry just understand basic and you will be fine. Best is to read this or complete trail itself.

我必须使用用户套接字(我知道RMI更好)

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

您无法像这样进行比较,最后无论是RMI,CORBA,RPC等.在客户端都有一个套接字,而在服务器端会有一个套接字.以防万一-服务器端套接字+客户端套接字=服务器和客户端之间的唯一连接.

You can't compare like this, in the end whether it is RMI, CORBA, RPC etc. etc., there will be a socket at client side and there will be a socket at server side. Just in case - server side socket + client side socket = unique connection between server and client.

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

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


    }

}

这篇关于客户端服务器多线程套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆