以下是客户端
package 网络编程.聊天小程序;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Date;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws IOException, InterruptedException {
//创建套接字
Socket sk = new Socket(InetAddress.getLocalHost(), 11111);
//发送数据
byte[] bytes = new byte[1024];
int len;
//获取输出,输出流
Scanner sc = new Scanner(System.in);
System.out.println("请选择选项 1 进入聊天室 2 传送文件到服务端 3 退出");
String nextInt = sc.nextLine();
while (true) {
if (nextInt.equals("1")||nextInt.equals("2")||nextInt.equals("3")) {
if (nextInt.equals("1")) {
OutputStream os = sk.getOutputStream();
//写数据
os.write("1".getBytes());
while (true) {
System.out.println();
System.out.println("系统:请发送消息给服务端" + new Date());
InputStream in = System.in;
os = sk.getOutputStream();
//写数据
len = in.read(bytes);
os.write(bytes, 0, len);
System.out.println("系统:等待服务端消息" + new Date());
InputStream is = sk.getInputStream();
byte[] bytes1 = new byte[1024];
int read = is.read(bytes1);
String back = new String(bytes1, 0, read);
System.out.println("系统:接收到服务端消息 = " + back + new Date());
System.out.println("---------");
System.out.println("请选择下一步操作 1 继续聊天 2 传送文件到服务端 3 退出");
nextInt = sc.nextLine();
if (!nextInt.equals("1")) {
break;
}
os.write("1".getBytes());
}
}
if (nextInt.equals("2")) {
OutputStream os = sk.getOutputStream();
//写数据
os.write("2".getBytes());
System.out.println("请输入文件的地址(绝对地址,必须是文本类型)!");
String address = sc.nextLine();
FileInputStream fis = new FileInputStream(address);
byte[] fileBytes = new byte[1024];
int fileLen;
while ((fileLen = fis.read(fileBytes)) != -1) {
//传给服务器
os.write(fileBytes, 0, fileLen);
}
//todo
//获取传送文件的服务器返回结果
InputStream is = sk.getInputStream();
byte[] filebytes = new byte[1024];
int read = is.read(filebytes);
System.out.println("服务端端消息 : "+new String(filebytes, 0, read));
//关流
fis.close();
System.out.println("请选择下一步操作 1 继续聊天 2 传送文件到服务端 3 退出");
nextInt = sc.nextLine();
}
if (nextInt.equals("3")) {
OutputStream os = sk.getOutputStream();
//写数据
os.write("3".getBytes());
sk.shutdownOutput();
break;
}
}else {
System.out.println("请输入正确的选择!!!");
System.out.println("请选择选项 1 进入聊天室 2 传送文件到服务端 3 退出");
nextInt = sc.nextLine();
}
}
//关闭
// 套接字以及输出流,接受服务器通知
System.out.println("您已经退出聊天室");
sk.close();
}
}
以下是服务端
package 网络编程.聊天小程序;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.UUID;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class Server {
public static void main(String[] args) throws IOException {
//创建一个集合,记录socket
Vector sockets = new Vector<>();
//创建服务端套接字
ServerSocket ss = new ServerSocket(11111);
//创建线程池
ExecutorService es = Executors.newFixedThreadPool(100);
//绑定套接字
for (int i = 0; i < 10; i++) {
es.submit(new Runnable() {
@Override
public void run() {
try {
Socket accept = ss.accept();
//添加集合
sockets.add(accept);
InetAddress inetAddress = accept.getInetAddress();
String hostName = inetAddress.getHostName();
InputStream is=accept.getInputStream();
byte[] bytes = new byte[1024];
int len;
while (true) {
if (accept.isClosed()){
System.out.println(hostName+"断开连接了");
break;
}
len= is.read(bytes);
//客户端将用进行的操作
String result = new String(bytes, 0, len);
if (result.equals("1")) {
while ((len = is.read(bytes)) != -1) {
System.out.println("-----当前用户" + hostName + "----");
System.out.println(hostName + "系统:接收到客户端消息" + new Date());
System.out.print("客户端消息 : "+new String(bytes, 0, len));
//返回信息
System.out.println(hostName + "系统:请返回消息给客户端" + new Date());
InputStream in = System.in;
byte[] bytes1 = new byte[1024];
int len1;
len1 = in.read(bytes1);
accept.getOutputStream().write(bytes1, 0, len);
System.out.println(hostName + "系统:成功发送消息" + new Date());
System.out.println("结束-----"+hostName + "---------");
System.out.println();
break;
}
}
if (result.equals("2")) {
System.out.println(hostName+"请求传送文件");
//写文件
bytes = new byte[1024];
FileOutputStream fos = new FileOutputStream( "C:\\Users\\Administrator.DESKTOP-3B5FM5P\\Desktop\\"+UUID.randomUUID() + ".txt");
//todo
while ((len = is.read(bytes)) != -1) {
fos.write(bytes,0,len);
//少于1024说明读完了,不用在等客户端传送数据了
if (len<1024){
break;
}
}
System.out.println(hostName+"文件上传成功!");
accept.getOutputStream().write((hostName+"上传成功!").getBytes());
//关流
fos.close();
}
if (result.equals("3")) {
System.out.println(hostName+"断开了连接!");
accept.close();
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
//在用一个线程,记录当前服务器连接的客户端数量
es.submit(new Runnable() {
@Override
public void run() {
while (true) {
//每隔一分钟获取一次结果
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
getClints(sockets);
}
}
});
}
//todo 明明已经关闭了客户互动,为社么还是在线状态
//获取当前服务端连接的客户端数量
public static void getClints(Vector vector){
AtomicInteger count=new AtomicInteger();
//遍历集合
for (Socket socket : vector) {
if (!socket.isClosed()){
System.out.println(socket.getInetAddress().getHostName()+" 状态 "+(!socket.isClosed())+" 时间 "+ LocalDateTime.now());
count.incrementAndGet();
}
}
System.out.println("一分钟刷新一次 当前在线用户数量 : "+count);
}
}
基础知识写的一个聊天室
用到了线程池,网络编程,IO流的知识