利用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()方法,只不多多了换行而已
而客户端会产生两个线程,一个线程是用来获取标准键盘输入流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()方法,只不多多了换行而已
相关文章推荐
- 利用多线程和TCP技术,实现客户端与服务端之间的通信
- 服务端利用多线程TCP同时接受多个客户端发送文件
- 利用Tcp和socket实现的客户端与服务端的简单通信
- Java基础---Java---网络编程---TCP的传输、客户端和服务端的互访、建立一个文本转换器、编写一个聊天程序
- Java基础---Java---网络编程---TCP的传输、客户端和服务端的互访、建立一个文本转换器、编写一个聊天程序
- java 使用TCP实现单聊的功能。(客户端和服务端聊天)
- 通过TCP实现客户端服务端简单链接案例
- 【TCP协议练习】服务端利用多线程TCP同时接受多个客户端发送文件
- Go实战--实现一个简单的tcp服务端和客户端(The way to go)
- Linux c实现服务端与客户端聊天
- python+soket实现 TCP 协议的客户/服务端中文(自动回复)聊天程序
- 通过网络编程、文件IO、多线程,实现客户端和服务端对话。
- C#中TCP实现多个客户端与服务端数据与文件的传输
- Qt中利用TCP实现多个客户端之间相互发送消息系以及服务器的群发信息
- C#利用TcpListener和TcpClient类实现服务器和客户端的通信
- 基于websocket实现与图灵机器人即时聊天,服务端向客户端推送消息
- linux网络编程之用多线程实现客户端到服务端的通信(基于udp)
- 利用AsyncSocket来实现客户端与服务端,客户端与客户端的通信
- java学习之利用TCP实现的简单聊天示例代码
- 基于freeSWITCH的sip协议利用WebRTC 实现实时视频聊天