2016-03-05 30 views
-1

我正在编写一个java应用程序。我试图用相同的程序和端口在本地主机上发送数据和接收数据。我的代码正在工作,但只收到第一个数据。例如,我尝试先发送“1”,将其打印到控制台。然后我尝试发送“2”,但不打印。Java套接字只发送一次数据

Main.java:

package sample; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class Main extends Application { 

    @Override 
    public void start(Stage primaryStage) throws Exception{ 
     Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); 
     primaryStage.setTitle("Hello World"); 
     primaryStage.setScene(new Scene(root, 360, 150)); 
     primaryStage.show(); 
    } 


    public static void main(String[] args) { 
     launch(args); 
    } 
} 

Controller.java:

package sample; 

import javafx.fxml.FXML; 
import javafx.scene.control.TextField; 

import java.io.BufferedReader; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class Controller { 

    @FXML 
    TextField gonderilecekVeri = new TextField(); 
    TextField gonder_ip = new TextField(); 

    int port = 12345; 
    ServerSocket dinle; 

    public void portuDinle() { 
     System.out.println("Portu Dinliyor..."); 

     new Thread(() -> { 
      Socket baglanti; 
      String veri = null; 
      try { 
       dinle = new ServerSocket(port); 
       baglanti = dinle.accept(); 
       BufferedReader gelen = new BufferedReader(new InputStreamReader(baglanti.getInputStream())); 
       veri = gelen.readLine(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      if (veri != null) { 
       System.out.println(veri); 
      } 

     }).start(); 
    } 

    public void dinlemeDurdur() { 
     System.out.println("Dinleme Durdu"); 

     try { 
      dinle.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void veriGonder() { 
     String veri = gonderilecekVeri.getText(); 
     String ipAdresi = gonder_ip.getText(); 
     int gondermePortu = 12345; 

     try { 
      Socket gonder = new Socket(ipAdresi, gondermePortu); 
      DataOutputStream outToServer = new DataOutputStream(gonder.getOutputStream()); 
      outToServer.writeBytes(veri + '\n'); 
      outToServer.flush(); 
      outToServer.close(); 
      gonder.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

我没试过吗?

*我说收到只有第一个数据,因为我尝试2个不同的应用程序发送数据和结果是相同的两个。

*我在接收数据并重新启动后尝试关闭套接字。如果我手动执行此操作(使用我编写的javafx gui,触发Controller.java中的dinlemeDurdur函数)。但是,当我尝试关闭并重新启动代码(打印数据后)时,它不起作用。

我的意思是上面(在Controller.java portuDinle功能):

  if (veri != null) { 
      System.out.println(veri); 
      try { 
       dinle.close(); 
       dinle = new ServerSocket(port); 
       baglanti = dinle.accept(); 
       BufferedReader gelen = new BufferedReader(new InputStreamReader(baglanti.getInputStream())); 
       veri = gelen.readLine(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

这工作,但我很好奇我必须重新启动服务器这样吗? (Controller.java portuDinle func。)

 if (veri != null) { 
      System.out.println(veri); 
      dinlemeDurdur(); 
      portuDinle(); 
     } 

顺便说一句,没有错误。控制台很干净。只有第一个数据是打印。

回答

1

您只接受一个连接。您需要循环拨打accept()。根据您的应用程序协议,您可能还需要在循环中调用readLine(),直到它返回null。如果您想同时为客户端提供服务,则需要为每个接受的连接启动一个新线程,而不是在接受线程中内联处理它的I/O。

+0

如果你希望它们同时被服务,你应该为每个客户端启动一个新线程。我已经说过了。评论设施不是在这里教你如何开始一个线程。有很多例子。请参阅Java教程的“自定义网络”部分。 – EJP

+0

寻找NIO。从http://tutorials.jenkov.com/java-nio/index.html开始。看看相关的SE问题:http://stackoverflow.com/questions/4752130/java-thread-per-connection-model-vs-nio和http://stackoverflow.com/questions/10113902/old-io-线程每个客户端的模型 - 或NIO反应器图案。 –

+0

@RasimAndıran您每次接受新客户时都会开始一个新线程。我现在说过三次。你知道什么部分? 1000个线程没有任何问题,有100k线程的服务器。直到你知道你有一个线程问题时,你应该忽略看NIO的建议。 – EJP