/*
构造方法:
public Socket(String hostip地址, int port端口号)
注意: 只要创建客户端Socket对象,就会完成与服务器端的三次握手,建立与服务器端的连接
//1.创建客户端Socket对象,指定要连接的服务器的ip地址和端口号
Socket client = new Socket("127.0.0.1",6666);
//2.客户端Socket对象调用getOutputStream方法,获取客户端的字节输出流对象
常用方法: OutputStream netOs = client.getOutputStream();
getOutputStream(): 获取客户端的字节输出流对象,用来给服务器端发送请求信息
//3.客户端的字节输出流对象调用write方法给服务器写出字节数据(请求)
netOs.write("你好服务器!!!".getBytes());
getInputStream(): 获取客户端的字节输入流对象,用读取服务器端发送回来的响应信息
//4.客户端Socket对象调用getInputStream方法,获取客户端的输入流对象
InputStream netIs = client.getInputStream();
//5.客户端的字节输入流对象调用read方法,读取服务器端发送回来的字节数据(响应)
//假设服务器响应的数据不多,只需要使用1024长度的字节数组读取一次即可
int len;
byte[] bs = new byte[1024];
len = netIs.read(bs);
System.out.println("客户端收到服务器的响应消息: "+new String(bs,0,len));
ServerSocket(int port端口号,必须和客户端访问的端口号保持一致)
注意: 服务器端不用指定ip地址,在哪台机器上运行,就是用该机器的ip地址
//1.创建服务器端ServerSocket对象,指定端口号(必须和客户端访问的端口号保持一致)
ServerSocket server = new ServerSocket(6666);
java.net.ServerSocket类: TCP通信的服务器端
常用方法:
public Socket accept(): 服务器端获取到连接服务器的客户端的Socket对象
返回值类型:
java.net.Socket类: TCP通信的客户端
//2.服务器端ServerSocket对象调用accept方法,获取到连接服务器的客户端的Socket对象
Socket client = server.accept();
常用方法:
//3.客户端Socket对象调用getInputStream方法,获取服务器端的字节输入流对象
InputStream netIs = client.getInputStream();
public InputStream getInputStream():
获取服务器端的字节输入流对象,用读取客户端发送过来的请求信息
public OutputStream getOutputStream():
获取服务器端的字节输出流对象,用来给客户端发送响应信息
//5.客户端Socket对象调用getOutputStream方法,获取服务器端的字节输出流对象
OutputStream netOs = client.getOutputStream();
Thread.sleep(8000);
导致服务器端的read方法的结果是-1
客户端数据发送完毕后,调用方法: shutDownOutputStream():
销毁客户端的字节输出流,相当于给服务 器发送-1
int len;
byte[] bs = new byte[1024];
while ((len = fis.read(bs)) != -1) {
netOs.write(bs,0,len);
}
client.shutdownOutput();
//5.客户端Socket对象调用getInputStream方法,获取客户端字节输入流对象(读取服
//4.创建文件字节输出流FileOutputStream对象,绑定服务器端的目标文件
FileOutputStream fos = new FileOutputStream("day14\upload\to\jzc.flv");
//产生尽可能不重复的文件名
String fileName = System.currentTimeMillis() + "" + Math.abs(new Random().nextInt()) + ".flv";
//创建目标文件对应的File对象
File file = new File("day14\upload\to",fileName);
//多客户端上传(单线程版本)
//为当前新连接进来的客户端开启一条新的线程执行文件上传任务
new Thread(new Runnable() {
@Override
public void run() { }
}).start();
}
*/
/*
问题: 服务器端: 只支持上传一次 修改为: 多客户端上传(单线程版本)
解决方案: 服务器端改为多线程版本,来一个客户端开启一个线程
最后: 使用线程池优化
*/ public class Demo06UpLoadServerThreadPool { public static void main(String[] args) throws IOException { //String str = UUID.randomUUID().toString().replace("-",""); //使用工具类Executors调用静态方法newFixedThreadPool创建有3个线程的线程池对象 ExecutorService pool = Executors.newFixedThreadPool(3); //1.创建服务器端ServerSocket对象,指定端口号 ServerSocket server = new ServerSocket(7777); //死循环,模拟服务器一直在运行 while (true) { //2.服务器端ServerSocket对象调用accept方法,获取连接服务器的客户端Socket对象 Socket client = server.accept(); //使用线程池对象调用submit方法,提交当前客户端的文件上传任务 pool.submit(new UpLoadTask(client)); }
}
} ///* // 定义Runnable接口的实现类 // 需要使用构造方法,传递客户端Socket对象 // */ //public class UpLoadTask implements Runnable { // //进行文件上传的当前客户端Socket对象 // private Socket client; // // public UpLoadTask(Socket client) { // this.client = client; // } //} //