1.1 多发多收
客户端:
package Mysocketnet.MyTCP.TCPExercises.exercise2;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
/*
* 客户端:发送一条数据,接收服务端反馈的消息并打印
* 服务器:接收数据并打印,再给客户端反馈消息
* */
public class client2 {
public static void main(String[] args) throws IOException {
//首先创建Socket对象
Socket socket = new Socket("127.0.0.1", 10087);
//在通道当中获取到输出流
OutputStream os = socket.getOutputStream();
//键盘输入写入数据
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("请输入传输的话");
String str = sc.nextLine();
//退出传输的条件
if (str.equals("886")){
System.out.println("结束聊天");
break;
}
os.write(str.getBytes());
System.out.println("传输成功");
}
//清理资源
os.close();
socket.close();
}
}
服务端:
package Mysocketnet.MyTCP.TCPExercises.exercise2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 客户端:发送一条数据,接收服务端反馈的消息并打印
* 服务器:接收数据并打印,再给客户端反馈消息
* */
public class service2 {
public static void main(String[] args) throws IOException {
//创建ServerSocket
ServerSocket ss = new ServerSocket(10087);
//接收数据
Socket accept = ss.accept();
//获取到里面的输入流
BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
int len;
while ((len = br.read()) != -1){
System.out.print((char) len);
}
//关闭资源
accept.close();
ss.close();
}
}
1.2 接收和反馈
客户端:
package Mysocketnet.MyTCP.TCPExercises.exercise2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.annotation.ElementType;
import java.net.Socket;
/*
* 客户端:发送一条数据,接收服务端反馈的消息并打印
* 服务器:接收数据并打印,再给客户端反馈消息
* */
public class client2 {
public static void main(String[] args) throws IOException {
//创建Socket对象
Socket socket = new Socket("127.0.0.1", 10086);
//创建输出流
OutputStream os = socket.getOutputStream();
String str = "鸭四了你";
os.write(str.getBytes());
//注意:这里要写结束标志,这样才能让服务器接收到已发送完毕
socket.shutdownOutput();
//这里就是来接受到服务器返回的数据
//创建输入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int len ;
while ((len = br.read()) != -1){
System.out.print((char) len);
}
//清理资源
socket.close();
}
}
服务端:
package Mysocketnet.MyTCP.TCPExercises.exercise2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 客户端:发送一条数据,接收服务端反馈的消息并打印
* 服务器:接收数据并打印,再给客户端反馈消息
* */
public class service2 {
public static void main(String[] args) throws IOException {
//创建ServeSocket对象
ServerSocket ss = new ServerSocket(10086);
//接收数据
Socket accept = ss.accept();
//获取输入流
BufferedReader br = new BufferedReader(new InputStreamReader(accept.getInputStream()));
int len = 0;
while ((len = br.read()) != -1){
System.out.print((char) len);
}
//返回数据
//创建输出流
OutputStream os = accept.getOutputStream();
os.write("我谢谢你".getBytes());
//释放资源
accept.close();
ss.close();
}
}
1.3 上传文件
客户端:
package Mysocketnet.MyTCP.TCPExercises.exercise3;
import java.io.*;
import java.net.Socket;
/*
* 客户端:将本地文件上传到服务器。接收服务器的反馈
* 服务器:接收客户端上传的文件,上传完毕之后给出反馈
* */
public class client3 {
public static void main(String[] args) throws IOException {
//创建Socket对象
Socket socket = new Socket("127.0.0.1", 10086);
//创建读取文件的输入流
BufferedInputStream br = new BufferedInputStream(new FileInputStream("E:\\Java文件夹\\DuoXianCheng\\src\\cilent.txt"));
//创建通道的输出流
OutputStream os = socket.getOutputStream();
//定义传输的第三方变量
int len;
byte[] bytes = new byte[1024];
while ((len = br.read(bytes)) != -1){
os.write(bytes,0,len);
}
//清理资源
br.close();
//关闭输出流,说明传输成功,来接受反馈
socket.shutdownOutput();
BufferedReader br2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int b;
while ((b = br2.read()) != -1){
System.out.print((char) b);
}
//清理资源
socket.close();
}
}
服务端:
package Mysocketnet.MyTCP.TCPExercises.exercise3;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 客户端:将本地文件上传到服务器。接收服务器的反馈
* 服务器:接收客户端上传的文件,上传完毕之后给出反馈
* */
public class service3 {
public static void main(String[] args) throws IOException {
//创建ServerSocket对象
ServerSocket ss = new ServerSocket(10086);
//接收数据。并且添加通道的输入流
Socket accept = ss.accept();
BufferedInputStream br = new BufferedInputStream(accept.getInputStream());
//创建输出流写到本地
BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("E:\\Java文件夹\\DuoXianCheng\\src\\service.txt"));
int len;
byte[] bytes = new byte[1024];
while ((len = br.read(bytes)) != -1){
bw.write(bytes,0,len);
}
//清理资源
bw.close();
//反馈数据
OutputStream os = accept.getOutputStream();
os.write("我谢谢你啊".getBytes());
//清理资源
accept.close();
ss.close();
}
}
1.4 文件名重复问题
就是利用UUID来创建不同名字的文件
String name = UUID.randomUUID().toString().replace("-", "");
BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("E:\\Java文件夹\\DuoXianCheng\\src\\"+name+".txt"));
1.5 上传文件(多线程版)
如果这里只进行循环的话,那么就会造成每开启一个线程就回去连接服务器,如果这个时候,还没传输完数据的话,就会导致程序出现错误,所以应该通过循环+多线程的方式
客户端:
package Mysocketnet.MyTCP.TCPExercises.exercise4;
import java.io.*;
import java.net.Socket;
/*
* 客户端:将本地文件上传到服务器。接收服务器的反馈
* 服务器:接收客户端上传的文件,上传完毕之后给出反馈
* */
public class client4 {
public static void main(String[] args) throws IOException {
//创建Socket对象
Socket socket = new Socket("127.0.0.1", 10086);
//创建读取文件的输入流
BufferedInputStream br = new BufferedInputStream(new FileInputStream("E:\\Java文件夹\\DuoXianCheng\\src\\cilent.txt"));
//创建通道的输出流
OutputStream os = socket.getOutputStream();
//定义传输的第三方变量
int len;
byte[] bytes = new byte[1024];
while ((len = br.read(bytes)) != -1){
os.write(bytes,0,len);
}
//清理资源
br.close();
//关闭输出流,说明传输成功,来接受反馈
socket.shutdownOutput();
BufferedReader br2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int b;
while ((b = br2.read()) != -1){
System.out.print((char) b);
}
//清理资源
socket.close();
}
}
服务端:
package Mysocketnet.MyTCP.TCPExercises.exercise4;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 客户端:将本地文件上传到服务器。接收服务器的反馈
* 服务器:接收客户端上传的文件,上传完毕之后给出反馈
* */
public class service4 {
public static void main(String[] args) throws IOException {
//创建ServerSocket对象
ServerSocket ss = new ServerSocket(10086);
while (true){
//接收数据。并且添加通道的输入流
Socket accept = ss.accept();
//创建多线程,达到每个任务对应一个线程
new Mythread(accept).start();
}
}
}
多线程:
package Mysocketnet.MyTCP.TCPExercises.exercise4;
import java.io.*;
import java.net.Socket;
import java.util.UUID;
public class Mythread extends Thread{
//创建空参构造将Socket对象传入
public static Socket accept;
public Mythread(Socket accept){
this.accept = accept;
}
@Override
public void run() {
try {
BufferedInputStream br = new BufferedInputStream(accept.getInputStream());
//创建输出流写到本地
String name = UUID.randomUUID().toString().replace("-", "");
BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("E:\\Java文件夹\\DuoXianCheng\\src\\"+name+".txt"));
int len;
byte[] bytes = new byte[1024];
while ((len = br.read(bytes)) != -1){
bw.write(bytes,0,len);
}
//清理资源
bw.close();
//反馈数据
OutputStream os = accept.getOutputStream();
os.write("我谢谢你啊".getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
//清理资源
if (accept != null){
try {
accept.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
1.7 利用线程池优化1.6的题目
优化代码如下:
//创建线程池对象
ThreadPoolExecutor pool = new ThreadPoolExecutor(
3,//创建的核心线程数量
24,//线程池的总大小
60,//线程存活时间
TimeUnit.SECONDS,//线程存活时间(单位)
new ArrayBlockingQueue<>(2),//队列数量
Executors.defaultThreadFactory(),//线程工厂,让他们如何创建一个线程
new ThreadPoolExecutor.AbortPolicy()//创建默认删除排队的
);
while (true){
//接收数据。并且添加通道的输入流
Socket accept = ss.accept();
//创建多线程,达到每个任务对应一个线程
// new Mythread5(accept).start();
pool.submit(new Mythread5(accept));
}