Java-Tcp通訊,解決只能第一次接收到資料
阿新 • • 發佈:2018-11-23
今天老師讓寫一個服務端和客戶端通訊的小程式,本以為很快就能寫完,但是在寫的過程中卻發現了自己很多的問題,所以寫篇部落格記錄一下
寫完測試的時候發現,客服端只能發第一次資料給服務端,後面傳送的服務端都接受不到
//服務端 serverSocket=new ServerSocket(12900); socket=serverSocket.accept(); inputStream=socket.getInputStream(); byte[] bytes = new byte[1024]; inputStream.read(bytes); String string = new String(bytes); System.out.println(string); //客戶端 String mess=message.getText(); outputStream=socket.getOutputStream(); outputStream.write(mess.getBytes()); message.setText("");
後面加上了迴圈,發現還是隻能傳送第一次資料
try { serverSocket=new ServerSocket(12900); while (true){ socket=serverSocket.accept();//一直阻塞直到有人連線它 inputStream=socket.getInputStream(); byte[] bytes = new byte[1024]; inputStream.read(bytes); String string = new String(bytes); // message.append(string+"\n"); System.out.println(string); } }
查了資料才知道,socket是阻塞式通訊,accep()是會阻塞的和,read()也會阻塞,一直到有東西連線為止,或者有資料可讀,所以在這個迴圈中,第一次的時候因為有客戶端連線,所以能夠執行後面的程式碼,輸出資料,但後面開始就沒有客戶端連線,所以就一直阻塞在accept(),導致後面的沒法執行
try { serverSocket=new ServerSocket(12900); socket=serverSocket.accept(); while (true){ inputStream=socket.getInputStream(); byte[] bytes = new byte[1024]; inputStream.read(bytes); String string = new String(bytes); // message.append(string+"\n"); System.out.println(string); } }
這樣子就能夠實現客戶端一直給服務端傳送資料了
我對上面的程式進行了下改進,加入了執行緒,每一次有客戶端連線時,就建立一個執行緒處理這個客戶端的收發資料,也可藉此實現多客戶端向服務端通訊。
服務端執行緒類:
public class ServerThread extends Thread {
private Socket socket;
InputStream inputStream
public ServerThread(Socket socket){
this.socket=socket;
}
public void run(){
try {
while (true){
inputStream=socket.getInputStream();
byte[] bytes = new byte[1024];
inputStream.read(bytes);
String string = new String(bytes);
System.out.println(string);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
服務端:
System.out.println("wait client connect....");
serverSocket=new ServerSocket(8808);
while (true){
socket=serverSocket.accept();//有連線會返回一個Socket,其作為引數傳給服務端執行緒類
System.out.println("client successed !");
new ServerThread(socket).start();//有新的連線就建立一個對應的執行緒
}
加入執行緒不好的地方就是,當執行緒多了會佔記憶體,而你每個執行緒只執行一點點事情,就會造成記憶體浪費,而且執行緒多了,Cpu會在各個執行緒來回切換,造成Cpu效率低
客戶端:
socket=new Socket("localhost", 12900);
String mess=message.getText();
outputStream=socket.getOutputStream();
outputStream.write(mess.getBytes());
message.setText("");
這是本人結合網上的方法,如有不對或者效率更好的方法,歡迎指出和請教。
其實,有個點我沒明白,我沒關閉輸入流和Socket,不是應該是一直連線的嗎能夠一直接收到資料,為啥還需要迴圈才能一直接收到資料呢,要是有大佬能看到我這篇,希望幫我解答下,提前謝謝啦