客戶端再起一個線程來負(fù)責(zé)等待不就行了,多線程處理。還有服務(wù)端想高效處理客戶端消息,建議用NIO機(jī)制來處理,否則客戶端很快,服務(wù)端不能很快處理,也沒意義
墾利網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站開發(fā)等網(wǎng)站項目制作,到程序開發(fā),運營維護(hù)。創(chuàng)新互聯(lián)建站于2013年成立到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站。
將
Socket Socket=ServerSocket.accept();
System.out.println("IP地址"+Socket.getInetAddress()+"端口"+Socket.getPort()+"已經(jīng)連接到本機(jī)");
BufferedReader read = new BufferedReader(new InputStreamReader(Socket.getInputStream(),"UTF-8"));
PrintWriter pw =new PrintWriter(Socket.getOutputStream(),true);
拿到while循環(huán)外面,這樣服務(wù)器端只為第一個連接的客服端服務(wù),程序會正常?;蛘邔ocket=ServerSocket.accept();返回的sock交給寧一個線程處理,然后循環(huán)調(diào)用String st=read.readLine();讀取數(shù)據(jù),這樣就是一個比較標(biāo)準(zhǔn)的服務(wù)器端了,為每一個連進(jìn)來的客服端,開一個單獨的線程為之服務(wù)。
主要要理解Socket=ServerSocket.accept();這句代碼,返回的Socket是針對單獨的一個客戶端的,當(dāng)沒有客戶端連接時,這句代碼會阻塞,直到有客戶端連接進(jìn)來生成的與之對應(yīng)的客戶端。
現(xiàn)在報錯是因為,與客戶端相對應(yīng)Socket,讀了一行數(shù)據(jù),就銷毀了,然后又循環(huán)到Socket=ServerSocket.accept();去等待一個新的連接。而客戶端還往已經(jīng)銷毀的socket發(fā)數(shù)據(jù),當(dāng)然客戶端會拋Connection reset。
有兩個類,服務(wù)器和客戶端、
服務(wù)器類代碼:
package chat;
import java.io.*;
import java.net.*;
import java.util.*;
/*服務(wù)器類*/
public class Server {
public ListSocket socketList = new ArrayListSocket();//存放所有連接的客戶端的集合
public ServerSocket server;//服務(wù)器
public int portNum;//端口號
public Server(int portNum){
this.portNum = portNum;
}
public void innit(){
try {
server = new ServerSocket(portNum);
System.out.println("服務(wù)器開啟成功!");
int socketNum = 0;
while(true){
Socket socket = server.accept();//被動等待客戶端的連接
socketNum++;
System.out.println("第"+socketNum+"個客戶端連接成功?。?);
socketList.add(socket);//連接的客戶端存放到集合里面
new RWThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
class RWThread extends Thread{//接收和發(fā)送消息的線程
public Socket socket;
public RWThread(Socket socket){
this.socket = socket;
}
public void run() {
super.run();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
String message = br.readLine();
System.out.println(message);//接收客戶端發(fā)來的消息
for(int i=0;isocketList.size();i++){//發(fā)送給所有連接的客戶端
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socketList.get(i).getOutputStream()));
pw.println(message);
pw.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int portNum = 8888;//創(chuàng)建服務(wù)器的端口號
Server server = new Server(portNum);
server.innit();
}
}
客戶端類:
package chat;
import java.io.*;
import java.net.*;
import java.util.*;
/*客戶端類*/
public class Client {
public Socket socket;
public Client(){
Scanner sca = new Scanner(System.in);
try {
socket = new Socket("127.0.0.1",8888);//創(chuàng)建客戶端
new ReadThread(socket).start();//開啟讀取從服務(wù)器端發(fā)來的信息
while(true){
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
String message = sca.nextLine();
pw.println(message);//向服務(wù)器發(fā)送信息
pw.flush();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
System.out.println("錯誤:服務(wù)器未開啟?。?!");
}
}
class ReadThread extends Thread{//讀取服務(wù)器發(fā)來信息的線程
public Socket socket;
public ReadThread(Socket socket){
this.socket = socket;
}
public void run() {
super.run();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
String message = br.readLine();
System.out.println(message);//輸出信息
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Client client = new Client();
}
}
現(xiàn)打開服務(wù)器類,然后可以打開多個客戶端進(jìn)行聊天