您的位置:首页 > 理论基础 > 计算机网络

利用TCP和多线程实现服务端和多个客户端建立实时聊天小案例

2018-01-03 11:04 891 查看
每当有一个客户端和服务端建立连接之后,服务端就会产生一个线程从而来产生一个Socket来和客户端连接

而客户端会产生两个线程,一个线程是用来获取标准键盘输入流InputStream,就是通过System.in来获得,和向服务端发送消息的输出流,另外一个线程就是用来接收服务端发送来的消息,获得输入流。



服务端:

package com.iotek.test;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatServer {

public static void main(String[] args) throws IOException {
ServerSocket server=new ServerSocket(8888);
int number=1;//用来保存客户端人数
while(true){
Socket socket=server.accept();
System.out.println("客户端"+number+"连接成功");
//服务端开启一个独立的线程来对客户进行读写操作
ServerStream runable=new ServerStream(socket, number);
new Thread(runable).start();
number++;
}
}

}

服务端线程:
package com.iotek.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ServerStream implements Runnable {

private Socket socket=null;
private int number;

public ServerStream(Socket socket,int number){
this.socket=socket;
this.number=number;
}

@Override
public void run() {
//String str=null;
try {
//获取和客户端连接的输入流
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//创建想该客户端发送信息的输出流
PrintWriter pw=new PrintWriter(socket.getOutputStream(),true);
while(true){
String str=br.readLine();
System.out.println("客户端"+number+": "+str);
pw.println(str.toUpperCase());
if(str.equals("over")){
System.out.println("客户端"+number+"已经断开连接");
break;
}

}
br.close();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}


客户端:
package com.iotek.test;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ChatClint {

public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket=new Socket("192.168.1.3",8888);
ClintStream runable=new ClintStream(socket);
ClintStreamInput input=new ClintStreamInput(socket);
new Thread(runable).start();
new Thread(input).start();

}

}


客户端用来获取标准键盘输入流:
package com.iotek.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ClintStream implements Runnable {

private Socket socket=null;

public ClintStream(Socket socket) {
this.socket=socket;
}

@Override
public void run() {
//String str=null;
try {
//客户端获取键盘输入流
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//客户端获取可以向服务端发送消息的输出流
PrintWriter pw=new PrintWriter(socket.getOutputStream(),true);
while(true){
String str=br.readLine();
pw.println(str);
if(str.equals("over")){
break;
}
}
br.close();
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}

}

}


客户端用来获取和服务端连接的输入流:
package com.iotek.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
//该类用于读取服务器端向客户端发来的信息
public class ClintStreamInput implements Runnable {

private Socket socket=null;

public ClintStreamInput(Socket socket) {
this.socket=socket;
}

@Override
public void run() {
String str=null;
try {
BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true){
str=reader.readLine();
if(str.equalsIgnoreCase("over")){
break;
}
System.out.println(str);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}

}

其实我们查看PrintWriter的源代码可以发现,PrintWriter的底层就是Writer,它的println()方法,其实就是调用了Writer的write()方法,只不多多了换行而已
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐