2017-06-02 46 views
0

我正在一個java客戶端服務器程序,但我很難創建一個tcp套接字,它將接收一個接一個的消息,並在請求發出後分別響應每個消息。因爲( - 1)在接收套接字字節期間收到的終止分隔符在套接字關閉後發生。如何在java中創建請求 - 響應tcp cprogram?

- 我想要達到的是例如 (插座連接如被暗示)
客戶端>> 「請求」
服務器>> 「響應」
客戶>>
...等等 「請求」
服務器>> 「響應」

我如何在JAVA中做到這一點? 每次我必須發送和接收消息時,是否必須關閉並打開套接字連接?

對不起,不能很好地解釋它! 提前謝謝!

+0

用線條或。 'readUTF()/ writeUTF()',或者長度單詞或者字符長度 - 值消息,或者序列化,或者XML,或者...太寬泛。 – EJP

回答

-1

MyServer的是服務器代碼

import java.io.*; 
import java.net.*; 

public class MyServer { 

    public static void main(String[] args) throws Exception{ 

     ServerSocket ss=new ServerSocket(6666); 
     Socket s = ss.accept();//establishes connection  

     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 

     //BufferedWriter dout = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 
     DataInputStream din = new DataInputStream(s.getInputStream()); 
     DataOutputStream dout = new DataOutputStream(s.getOutputStream()); 

     String str1 = ""; 
     String str2 = ""; 

     while(!str1.equals("stop")){ 

     str1 = din.readUTF();; 
     System.out.println("Client: " + str1); 

     str2 = br.readLine(); 

     dout.writeUTF(str2); 
     dout.flush(); 

     } 

     din.close(); 
     s.close(); 
     ss.close(); 

    } 
} 

MyClient是客戶機代碼

import java.io.*; 
import java.net.*; 

public class MyClient { 

    public static void main(String[] args) throws Exception { 

     Socket s = new Socket("localhost",6666); 

     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 

     //BufferedReader din = new BufferedReader(new InputStreamReader(s.getInputStream())); 
     DataInputStream din = new DataInputStream(s.getInputStream()); 
     DataOutputStream dout = new DataOutputStream(s.getOutputStream()); 

     String str1 = ""; 
     String str2 = ""; 
     while(!str1.equals("stop")){ 

     str1 = br.readLine(); 
     dout.writeUTF(str1); 
     dout.flush(); 

     str2 = din.readUTF(); 
     System.out.println("Server: " + str2); 

     } 

     dout.close(); 
     s.close(); 
    } 
} 

該代碼允許客戶端和服務器之間的雙向通信。 可以通過發送來自任何一方的停止消息來停止通信。

要記住,從客戶端發送第一消息以開始通信

+0

你需要明確地處理'EOFException',當你這樣做時,你不需要''停止''。 – EJP

-1

這是服務器多線程的示例:

Server.java

import java.net.ServerSocket; 
import java.net.Socket; 

public class Server implements Runnable{ 



    private ServerSocket socket = null; 
    private Socket sock = null; 
    private boolean running = false; 

    public Server(){ 
     try{ 
      socket = new ServerSocket(4444); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void run() { 
     while(!running){ 
      running = true; 
      System.out.println("Server : UP"); 
      try{ 
       sock = socket.accept(); 
      }catch(Exception e){ 
       System.out.println("Errore durante l'attesa di nuove connessioni."); 
       break; 
      } 
      ClientThread ct = new ClientThread(sock,this); 
      Thread t = new Thread(ct); 
      t.start(); 

      System.out.println("In attesa di connessioni..."); 

     } 

    } 

    public void stop(){ 
     if(running){ 
      running = false; 
      System.out.println("Server : DOWN"); 
      try{ 
       socket.close(); 
      }catch(Exception e){ 
       e.printStackTrace(); 
       return; 
      } 
     } 
    } 

    public boolean isRunning(){ 
     return running; 
    } 

} 

ClientThread.java

package Server; 

import java.io.ObjectOutputStream; 
import java.io.OutputStream; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.util.NoSuchElementException; 
import java.util.Scanner; 

public class ClientThread implements Runnable{ 

    private Scanner scan; 
    private PrintWriter pw; 
    private Socket sock; 
    private Server main_thread; 
    private boolean flag = false; 
    private boolean running = true; 
    private SenderThread st = null; 

    public ClientThread(Socket sock,Server server){ 
     this.sock = sock; 
     this.main_thread = server; 

    } 

    @Override 
    public void run() { 
     if(flag) 
      return; 
     flag = true; 
     try{ 
      scan = new Scanner(sock.getInputStream()); 
      pw = new PrintWriter(sock.getOutputStream()); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

     while(running){ 
      try{ 
      String cmd = scan.nextLine(); 
      if(cmd.equals("Start")){ 
       st = new SenderThread(pw); 
       Thread t = new Thread(st); 
       t.start(); 
      } 
      else if(cmd.equals("Stop")){ 
       st.stop(); 
      } 
      else{ 
       running = false; 
      } 
      }catch(NoSuchElementException e){ 
       running = false; 
       e.printStackTrace(); 
      } 
     } 

     try{ 
      sock.close(); 
      scan.close(); 
      pw.close(); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

    } 

} 

Listener.java

package Client; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.ObjectOutputStream; 
import java.io.OutputStream; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.util.Scanner; 

import javax.swing.JOptionPane; 

public class Listener implements ActionListener{ 

    private GuiClient frame; 
    private Socket socket; 
    private Scanner scan; 
    private PrintWriter pw; 
    private Receiver receiver = null; 

    public Listener(GuiClient gui){ 
     this.frame = gui; 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     String cmd = e.getActionCommand(); 
     if(cmd.equals("Connect")){ 
      if(frame.ip_textfield.getText() == "" || frame.port_textfield.getText() == ""){ 
       JOptionPane.showMessageDialog(null, "Dati insufficienti !!!"); 
      } 
      String address = frame.ip_textfield.getText(); 
      int port = Integer.parseInt(frame.port_textfield.getText()); 
      try{ 
       setupConnection(address,port); 
       frame.status_label.setText("SERVER UP"); 
      }catch(Exception e1){ 
       JOptionPane.showMessageDialog(null, "Impossibile stabilire una connessione con il server."); 
       e1.printStackTrace(); 
      } 
      frame.Start.setEnabled(true); 
      frame.Connect.setEnabled(false); 
      frame.Disconnect.setEnabled(true); 
      frame.Stop.setEnabled(false); 
     }else if(cmd.equals("Start")){ 
      //ricevi stringhe e mostrale a schermo 
      frame.Start.setEnabled(false); 
      frame.Stop.setEnabled(true); 
      frame.Connect.setEnabled(false); 
      frame.Disconnect.setEnabled(false); 
      pw.println(cmd); 
      pw.flush(); 
      try{ 
       receiver = new Receiver(frame.status_label,scan); 
      }catch(Exception e2){ 
       JOptionPane.showMessageDialog(null, "Impossibile ricevere stringhe..."); 
       e2.printStackTrace(); 
      } 
      System.out.println("Client : "+cmd); 
      Thread t = new Thread(receiver); 
      t.start(); 
     }else if(cmd.equals("Stop")){ 
      frame.Stop.setEnabled(false); 
      frame.Disconnect.setEnabled(true); 
      frame.Connect.setEnabled(false); 
      frame.Start.setEnabled(true); 
      try{ 
       pw.println(cmd); 
       pw.flush(); 
       JOptionPane.showMessageDialog(null, "Ricezione delle stringhe interrotta."); 
      }catch(Exception e1){ 
       e1.printStackTrace(); 
      } 
     }else if(cmd.equals("Disconnect")){ 
      frame.Connect.setEnabled(true); 
      frame.Disconnect.setEnabled(false); 
      frame.Start.setEnabled(false); 
      frame.Stop.setEnabled(false); 
      try{ 
       socket.close(); 
      }catch(Exception e1){ 
       e1.printStackTrace(); 
      } 
     } 

    } 

    private void setupConnection(String address, int port){ 
     try{ 
      socket = new Socket(address,port); 
      OutputStream os = socket.getOutputStream(); 
      scan = new Scanner(socket.getInputStream()); 
      pw = new PrintWriter(os); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

} 

監聽程序工作在gui客戶端後面; SenderThread和Receiver是其他java類來處理字符串(在這種情況下)。我希望能夠幫助你。

+0

錯誤的異常處理。如果在創建打印作者的掃描儀時出現異常,您將忽略它並繼續進行,就好像它沒有發生過一樣。如果有創建客戶端套接字或其流的異常,則您正在吞嚥它並讓客戶端繼續執行某個NPE。不要這樣寫代碼。依賴於前面'try'塊中代碼成功的代碼應該在try塊中,並且應允許異常傳播,而不是被無意中吞下。 – EJP