Socket编程之多客户端聊天室
/**
* 创建服务器
* 写出数据:输出流
* 读取数据:输入流
*/
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket server =new ServerSocket(9999);
Socket client =server.accept();
//写出数据
//输入流
DataInputStream dis = new DataInputStream(client.getInputStream());
String msg =dis.readUTF();
//输出流
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
dos.writeUTF("服务器-->"+msg);
dos.flush();
}
}
Client端
/**
* 创建客户端: 发送数据+接收数据
* 写出数据:输出流
* 读取数据:输入流
* 输入流 与输出流 在同一个线程内 应该 独立处理,彼此独立
*
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket client = new Socket("localhost",9999);
//控制台输入流
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
DataInputStream dis = new DataInputStream(client.getInputStream());
while(true){
String info =console.readLine();
//输出流
dos.writeUTF(info);
dos.flush();
//输入流
String msg =dis.readUTF();
System.out.println(msg);
}
}
}
聊天室,多客户端原理:
Server端:
/**
* 创建服务器
* 写出数据:输出流
* 读取数据:输入流
* @author Administrator
*
*/
public class Server {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
ServerSocket server =new ServerSocket(9999);
while(true){
Socket client =server.accept();
//写出数据
//输入流
DataInputStream dis = new DataInputStream(client.getInputStream());
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
while(true){
String msg =dis.readUTF();
System.out.println(msg);
//输出流
dos.writeUTF("服务器-->"+msg);
dos.flush();
}
}
}
}
Client端:
package com.bjsxt.net.tcp.chat.demo02;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 创建客户端: 发送数据+接收数据
* 写出数据:输出流
* 读取数据:输入流
*
输入流 与输出流 在同一个线程内 应该 独立处理,彼此独立
*
*
*
* @author Administrator
*
*/
public class Client {
/**
* @param args
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
Socket client = new Socket("localhost",9999);
new Thread(new Send(client)).start(); //一条路径
new Thread(new Receive(client)).start(); //一条路径
}
}
发送端:
package com.bjsxt.net.tcp.chat.demo02;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* 发送数据 线程
* @author Administrator
*
*/
public class Send implements Runnable{
//控制台输入流
private BufferedReader console;
//管道输出流
private DataOutputStream dos;
//控制线程
private boolean isRunning =true;
public Send() {
console =new BufferedReader(new InputStreamReader(System.in));
}
public Send(Socket client){
this();
try {
dos =new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
//e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dos,console);
}
}
//1、从控制台接收数据
private String getMsgFromConsole(){
try {
return console.readLine();
} catch (IOException e) {
//e.printStackTrace();
}
return "";
}
/**
* 1、从控制台接收数据
* 2、发送数据
*/
public void send(){
String msg = getMsgFromConsole();
try {
if(null!=msg&& !msg.equals("")){
dos.writeUTF(msg);
dos.flush(); //强制刷新
}
} catch (IOException e) {
//e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dos,console);
}
}
@Override
public void run() {
//线程体
while(isRunning){
send();
}
}
}
接受端:
package com.bjsxt.net.tcp.chat.demo02;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
/**
* 接收线程
* @author Administrator
*
*/
public class Receive implements Runnable {
//输入流
private DataInputStream dis ;
//线程标识
private boolean isRunning = true;
public Receive() {
}
public Receive(Socket client){
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dis);
}
}
/**
* 接收数据
* @return
*/
public String receive(){
String msg ="";
try {
msg=dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dis);
}
return msg;
}
@Override
public void run() {
//线程体
while(isRunning){
System.out.println(receive());
}
}
}
关闭流工具类:
package com.bjsxt.net.tcp.chat.demo02;
import java.io.Closeable;
/**
* 关闭流的方法
* @author Administrator
*
*/
public class CloseUtil {
public static void closeAll(Closeable... io){
for(Closeable temp:io){
try {
if (null != temp) {
temp.close();
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
第192集
尚学堂JAVA最全教程
配合JAVA300集视频课程,一集一个文档
本文档配合:java300集第一季192集
【最新文档更新请加入尚学堂www.bjsxt.cn】
【专业JAVA培训机构,真正零首付入学www.bjsxt.com】
聊天室,在上一个版本上增加对用户的代码如下:别的的代码在上一级直接拷贝即可:
Server:
package com.bjsxt.net.tcp.chat.demo02;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 创建服务器
* 写出数据:输出流
* 读取数据:输入流
* @author Administrator
*
*/
public class Server {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
ServerSocket server =new ServerSocket(9999);
while(true){
Socket client =server.accept();
//写出数据
//输入流
DataInputStream dis = new DataInputStream(client.getInputStream());
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
while(true){
String msg =dis.readUTF();
System.out.println(msg);
//输出流
dos.writeUTF("服务器-->"+msg);
dos.flush();
}
}
}
}
Client:
package com.bjsxt.net.tcp.chat.demo02;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 创建客户端: 发送数据+接收数据
* 写出数据:输出流
* 读取数据:输入流
*
输入流 与输出流 在同一个线程内 应该 独立处理,彼此独立
*
*/
public class Client {
/**
* @param args
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
Socket client = new Socket("localhost",9999);
new Thread(new Send(client)).start(); //一条路径
new Thread(new Receive(client)).start(); //一条路径
}
}
第193集
尚学堂JAVA最全教程
配合JAVA300集视频课程,一集一个文档
本文档配合:java300集第一季193集
【最新文档更新请加入尚学堂www.bjsxt.cn】
【专业JAVA培训机构,真正零首付入学www.bjsxt.com】
聊天室,增加私聊功能:
Server:
package com.bjsxt.net.tcp.chat.demo03;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* 创建服务器
* 写出数据:输出流
* 读取数据:输入流
* @author Administrator
*
*/
public class Server {
private List<MyChannel> all = new ArrayList<MyChannel>();
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
new Server().start();
}
public void start() throws IOException{
ServerSocket server =new ServerSocket(9999);
while(true){
Socket client =server.accept();
MyChannel channel = new MyChannel(client);
all.add(channel);//统一管理
new Thread(channel).start(); //一条道路
}
}
/**
* 一个客户端 一条道路
* 1、输入流
* 2、输出流
* 3、接收数据
* 4、发送数据
* @author Administrator
*
*/
private class MyChannel implements Runnable{
private DataInputStream dis ;
private DataOutputStream dos ;
private boolean isRunning =true;
public MyChannel(Socket client ) {
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dis,dos);
isRunning =false;
}
}
/**
* 读取数据
* @return
*/
private String receive(){
String msg ="";
try {
msg=dis.readUTF();
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dis);
isRunning =false;
all.remove(this); //移除自身
}
return msg;
}
/**
* 发送数据
*/
private void send(String msg){
if(null==msg ||msg.equals("")){
return ;
}
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dos);
isRunning =false;
all.remove(this); //移除自身
}
}
/**
* 发送给其他客户端
*/
private void sendOthers(){
String msg = this.receive();
//遍历容器
for(MyChannel other:all){
if(other ==this){
continue;
}
//发送其他客户端
other.send(msg);
}
}
@Override
public void run() {
while(isRunning){
sendOthers();
}
}
}
}
Client:
package com.bjsxt.net.tcp.chat.demo03;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 创建客户端: 发送数据+接收数据
* 写出数据:输出流
* 读取数据:输入流
*
输入流 与输出流 在同一个线程内 应该 独立处理,彼此独立
*/
public class Client {
/**
* @param args
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
Socket client = new Socket("localhost",9999);
new Thread(new Send(client)).start(); //一条路径
new Thread(new Receive(client)).start(); //一条路径
}
}
send:
package com.bjsxt.net.tcp.chat.demo03;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* 发送数据 线程
* @author Administrator
*
*/
public class Send implements Runnable{
//控制台输入流
private BufferedReader console;
//管道输出流
private DataOutputStream dos;
//控制线程
private boolean isRunning =true;
public Send() {
console =new BufferedReader(new InputStreamReader(System.in));
}
public Send(Socket client){
this();
try {
dos =new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
//e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dos,console);
}
}
//1、从控制台接收数据
private String getMsgFromConsole(){
try {
return console.readLine();
} catch (IOException e) {
//e.printStackTrace();
}
return "";
}
/**
* 1、从控制台接收数据
* 2、发送数据
*/
public void send(){
String msg = getMsgFromConsole();
try {
if(null!=msg&& !msg.equals("")){
dos.writeUTF(msg);
dos.flush(); //强制刷新
}
} catch (IOException e) {
//e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dos,console);
}
}
@Override
public void run() {
//线程体
while(isRunning){
send();
}
}
}
Receive:
package com.bjsxt.net.tcp.chat.demo03;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
/**
* 接收线程
* @author Administrator
*
*/
public class Receive implements Runnable {
//输入流
private DataInputStream dis ;
//线程标识
private boolean isRunning = true;
public Receive() {
}
public Receive(Socket client){
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dis);
}
}
/**
* 接收数据
* @return
*/
public String receive(){
String msg ="";
try {
msg=dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dis);
}
return msg;
}
@Override
public void run() {
//线程体
while(isRunning){
System.out.println(receive());
}
}
}
关闭流的基本工具:
package com.bjsxt.net.tcp.chat.demo03;
import java.io.Closeable;
/**
* 关闭流的方法
* @author Administrator
*
*/
public class CloseUtil {
public static void closeAll(Closeable... io){
for(Closeable temp:io){
try {
if (null != temp) {
temp.close();
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
第194集
尚学堂JAVA最全教程
配合JAVA300集视频课程,一集一个文档
本文档配合:java300集第一季194集
【最新文档更新请加入尚学堂www.bjsxt.cn】
【专业JAVA培训机构,真正零首付入学www.bjsxt.com】
聊天室,私聊的实现代码如下:
基于tcp: 面向连接 安全 可靠 效率低 ,类似于打电话
一、面向连接: 请求-相应 Request --Response
二、Socket编程
1、服务器: ServerSocket
2、客户端: Socket
package com.bjsxt.net.tcp.chat.demo04;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* 创建服务器
* 写出数据:输出流
* 读取数据:输入流
*/
public class Server {
private List<MyChannel> all = new ArrayList<MyChannel>();
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
new Server().start();
}
public void start() throws IOException{
ServerSocket server =new ServerSocket(9999);
while(true){
Socket client =server.accept();
MyChannel channel = new MyChannel(client);
all.add(channel);//统一管理
new Thread(channel).start(); //一条道路
}
}
/**
* 一个客户端 一条道路
* 1、输入流
* 2、输出流
* 3、接收数据
* 4、发送数据
*/
private class MyChannel implements Runnable{
private DataInputStream dis ;
private DataOutputStream dos ;
private boolean isRunning =true;
private String name;
public MyChannel(Socket client ) {
try {
dis = new DataInputStream(client.getInputStream());
dos = new DataOutputStream(client.getOutputStream());
this.name =dis.readUTF();
this.send("欢迎您进入聊天室");
sendOthers(this.name+"进入了聊天室",true);
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dis,dos);
isRunning =false;
}
}
/**
* 读取数据
* @return
*/
private String receive(){
String msg ="";
try {
msg=dis.readUTF();
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dis);
isRunning =false;
all.remove(this); //移除自身
}
return msg;
}
/**
* 发送数据
*/
private void send(String msg){
if(null==msg ||msg.equals("")){
return ;
}
try {
dos.writeUTF(msg);
dos.flush();
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dos);
isRunning =false;
all.remove(this); //移除自身
}
}
/**
* 发送给其他客户端
*/
private void sendOthers(String msg,boolean sys){
//是否为私聊 约定
if(msg.startsWith("@")&& msg.indexOf(":")>-1 ){ //私聊
//获取name
String name =msg.substring(1,msg.indexOf(":"));
String content = msg.substring(msg.indexOf(":")+1);
for(MyChannel other:all){
if(other.name.equals(name)){
other.send(this.name+"对您悄悄地说:"+content);
}
}
}else{
//遍历容器
for(MyChannel other:all){
if(other ==this){
continue;
}
if(sys){ //系统信息
other.send("系统信息:"+msg);
}else{
//发送其他客户端
other.send(this.name+"对所有人说:"+msg);
}
}
}
}
@Override
public void run() {
while(isRunning){
sendOthers(receive(),false);
}
}
}
}
Client:
package com.bjsxt.net.tcp.chat.demo04;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 创建客户端: 发送数据+接收数据
* 写出数据:输出流
* 读取数据:输入流
*
输入流 与输出流 在同一个线程内 应该 独立处理,彼此独立
加入名称
*/
public class Client {
/**
* @param args
* @throws IOException
* @throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("请输入名称:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String name = br.readLine();
if(name.equals("")){
return;
}
Socket client = new Socket("localhost",9999);
new Thread(new Send(client,name)).start(); //一条路径
new Thread(new Receive(client)).start(); //一条路径
}
}
Send:
package com.bjsxt.net.tcp.chat.demo04;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* 发送数据 线程
* @author Administrator
*
*/
public class Send implements Runnable{
//控制台输入流
private BufferedReader console;
//管道输出流
private DataOutputStream dos;
//控制线程
private boolean isRunning =true;
//名称
private String name;
public Send() {
console =new BufferedReader(new InputStreamReader(System.in));
}
public Send(Socket client,String name){
this();
try {
dos =new DataOutputStream(client.getOutputStream());
this.name =name;
send(this.name);
} catch (IOException e) {
//e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dos,console);
}
}
//1、从控制台接收数据
private String getMsgFromConsole(){
try {
return console.readLine();
} catch (IOException e) {
//e.printStackTrace();
}
return "";
}
/**
* 1、从控制台接收数据
* 2、发送数据
*/
public void send(String msg){
try {
if(null!=msg&& !msg.equals("")){
dos.writeUTF(msg);
dos.flush(); //强制刷新
}
} catch (IOException e) {
//e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dos,console);
}
}
@Override
public void run() {
//线程体
while(isRunning){
send(getMsgFromConsole());
}
}
}
Receive:
package com.bjsxt.net.tcp.chat.demo04;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
/**
* 接收线程
* @author Administrator
*
*/
public class Receive implements Runnable {
//输入流
private DataInputStream dis ;
//线程标识
private boolean isRunning = true;
public Receive() {
}
public Receive(Socket client){
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dis);
}
}
/**
* 接收数据
* @return
*/
public String receive(){
String msg ="";
try {
msg=dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
isRunning =false;
CloseUtil.closeAll(dis);
}
return msg;
}
@Override
public void run() {
//线程体
while(isRunning){
System.out.println(receive());
}
}
}
关闭流工具类:
package com.bjsxt.net.tcp.chat.demo04;
import java.io.Closeable;
/**
* 关闭流的方法
* @author Administrator
*
*/
public class CloseUtil {
public static void closeAll(Closeable... io){
for(Closeable temp:io){
try {
if (null != temp) {
temp.close();
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
}