2017-05-11 179 views
2

我正在开发一个软件,与套接字,设置与服务器的连接(我安装PgAdmin的数据库)。 我创建客户端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){ 

} 
} 

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

+1

转问这个问题的信息:http://stackoverflow.com/questions/10332799/client-server-client-communication-using-sockets ?rq = 1 –

+0

只需以字符串,对象,字节的形式发送它 - 套接字具有输出流,以便写入它。这就像你会写一些文件。 – Antoniossss

+0

但是当我创建登录表单时,客户端已经在运行?或者我在用户点击按钮时运行它?另外我需要控制用户的访问权限,所以生成的套接字必须为用户创建一个会话 – dvdLucka

回答

2

非常简短的回答:你需要做内connectToServer()方法private static Socket socket;private BufferedReader in;private PrintWriter out;局部变量。你的主要方法里面还有private static Client client;

较长的答案:

客户端服务器多线程的Socket

这是位值得商榷的,因为没有什么比“多线程插座”,你要么有一个“多线程服务器”或“单线程服务器”,这基本上意味着您的服务器能够处理/处理并发连接,否则就不会。

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

现在,在客户端,您将指定您的服务器套接字详细信息,您的做法socket = new Socket(address, port);,所以基本上将在您的“客户端”打开一个新的套接字,在您的末端使用一些随机端口号(请请注意,这不是一个随机的服务器端口号,在您的端部,JVM将从操作系统获取随机“可用”端口号用于通信),并且该套接字对象将表示与服务器的唯一连接。那么,您将访问该套接字上的输出流(将数据发送到服务器)和输入流(从服务器读取数据)。

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

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

因此,这是客户端接收字符串用户,但我需要 办?创建另一个socket连接?

是的,你应该每次创建一个新的客户端套接字并使用它,要么隐式地要么通过创建一个新的线程来进行通信,我已经在上面解释了你的情况。总的来说,每次你应该有一个新的套接字来与服务器进行通信。

请帮帮我,套接字让我发疯。

不要担心只是了解基本,你会没事的。最好是阅读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(); 
      } 
     } 


    } 

} 
+0

谢谢,我使用这个代码服务器,它的工作原理! – dvdLucka

+0

很酷。那么你有没有找到你正在寻找的答案,或者你有什么问题吗? – hagrawal