端口号
TCP通信
TCP通信的客户端
TCP通信的客户端——————向服务器发送连接请求,给服务器发送数据,读取服务器回写的数据。
表示客户端的类
java.net.Socket——————此类实现客户端套接字(也可以讲座“套接字”)。套接字是两台机器间通信的端点。
套接字——————————包含了IP地址和端口号的网络单位。
构造方法
- Socket(String host,int post)————创建一个流套接字并将其连接到指定主机的指定端口号。
参数
String host————————服务器主机的名称/服务器的IP地址
int post——————————服务器的端口号
成员方法 - OutputStream getOutputStream ( )——返回此套接字的输出流
- InputStream getInputStream ( )——返回此套接字的输入流
- void close()——————————关闭此套接字
实现步骤
1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号。
2.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象。
3.使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据。
4.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象。
5.使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据。
6.释放资源(Socket)。
注意
1.客户端和服务器端进行交互,必须使用Socket中提供的网络流,不能使用自己创建的流对象。
2.当我们创建客户端对象Socket的时候,就会去请求服务器和服务器经过3此握手建立连接通路。
这时如果服务器没有启动,那么就会抛出异常。
如果服务器已经启动,那么就可以进行交互了。
TCP通信的服务器端
TCP通信的服务器端——————接收客户端的请求,读取客户端发送的数据,给客户端回写数据。
表示客户端的类
java.net.ServerSocket——————此类实现服务端套接字。
套接字——————————包含了IP地址和端口号的网络单位。
构造方法
- ServerSocket(int post)————创建绑定到指定端口号的服务器套接字。
服务器端必须明确一件事情,必须的知道是哪个客户端请求的服务器。
所以可以使用accept方法获取到请求的客户端对象Socket。
成员方法 - Socket accept()———————侦听并接收此套接字的连接。
服务器的实现步骤
1.创建一个服务器ServerSocket对象和系统指定的端口号。
2.使用ServerSocket对象中的方法accept()获取到请求的客户端对象Socket。
3.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象。
4.使用网络字节输入流InputStream对象中的方法read,读取客户端发送的数据。
5.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象。
6.使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据。
7.释放资源(Socket,ServerSocket)。
注意
1.客户端和服务器端进行交互,必须使用Socket中提供的网络流,不能使用自己创建的流对象。
2.当我们创建客户端对象Socket的时候,就会去请求服务器和服务器经过3此握手建立连接通路。
这时如果服务器没有启动,那么就会抛出异常。
如果服务器已经启动,那么就可以进行交互了。
综合案例——文件上传
package cn.lrf.netDemo;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/*文件上传案例的客户端————————读取本地文件,上传到服务器,读取服务器回写的数据
* 明确
* 数据源——————D:\java2019_5_13\图片\do while.jpg
* 目的地——————服务器
* 1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源。
* 2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号。
* 3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
* 4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
* 5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传服务器
* 6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
* 7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据
* 8.释放资源(FileInputStream,Socket)*/
public class TCPClient {
public static void main(String[] args) throws IOException {
//1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源。
FileInputStream fis = new FileInputStream("D:\\java2019_5_13\\图片\\do while.jpg");
//2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号。
Socket socket = new Socket("127.0.0.1", 8888);
//3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
OutputStream os = socket.getOutputStream();
//4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
//5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传服务器
os.write(bytes, 0, len);
}
//6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
InputStream is = socket.getInputStream();
while ((len = fis.read(bytes)) != -1) {
//7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据
System.out.println(new String(bytes, 0, len));
}
//8.释放资源(FileInputStream,Socket)
fis.close();
socket.close();
}
}
package cn.lrf.netDemo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*文件上传案例的服务端————————读取客户端上传的文件,保存到服务器的硬盘,给客户端回写“上传成功”
* 明确
* 数据源——————客户端上传的文件
* 目的地——————服务器的硬盘D:\\java2019_5_13\\图片\\u
* 1.创建一个服务器端ServerSocket对象,构造方法中绑定服务器的IP地址和系统要指定的端口号。
* 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象。
* 3.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
* 4.判断D:\\java2019_5_13\\图片\\u文件夹是否存在,不存在则创建
* 5.创建一个本地字节输入流FileOutputStream对象,构造方法中绑定要输出的目的地。
* 6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
* 7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器硬盘上
* 8.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
* 9.使用网络字节输出流FileOutputStream对象中的方法readwrite给客户端回写“上传成功”
* 10.释放资源(FileOutputStream,Socket,ServerSocket)*/
public class TCPServer {
public static void main(String[] args) throws IOException {
//* 1.创建一个服务器端ServerSocket对象,构造方法中绑定服务器的IP地址和系统要指定的端口号。
ServerSocket server=new ServerSocket(8888);
// * 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象。
Socket socket=server.accept();
// * 3.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
InputStream is=socket.getInputStream();
// * 4.判断D:\\java2019_5_13\图片\\u文件夹是否存在,不存在则创建
File file=new File("D:\\java2019_5_13\\图片\\u");
if (!file.exists()){
file.mkdirs();
}
// * 5.创建一个本地字节输入流FileOutputStream对象,构造方法中绑定要输出的目的地。
FileOutputStream fos=new FileOutputStream(file+"\\do while.jpg");
// * 6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
int len=0;
byte[]bytes=new byte[1024];
while ((len=is.read())!=-1){
// * 7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器硬盘上
fos.write(bytes,0,len);
}
// * 8.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
// * 9.使用网络字节输出流FileOutputStream对象中的方法readwrite给客户端回写“上传成功”
socket.getOutputStream().write("上传成功".getBytes());
// * 10.释放资源(FileOutputStream,Socket,ServerSocket)
fos.close();
socket.close();
server.close();
}
}
综合案例——文件上传案例阻塞问题
综合案例——文件上传案例优化
package cn.lrf.netDemo;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
/*文件上传案例的服务端————————读取客户端上传的文件,保存到服务器的硬盘,给客户端回写“上传成功”
* 明确
* 数据源——————客户端上传的文件
* 目的地——————服务器的硬盘D:\\java2019_5_13\\图片\\u
* 1.创建一个服务器端ServerSocket对象,构造方法中绑定服务器的IP地址和系统要指定的端口号。
* 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象。
* 3.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
* 4.判断D:\\java2019_5_13\\图片\\u文件夹是否存在,不存在则创建
* 5.创建一个本地字节输入流FileOutputStream对象,构造方法中绑定要输出的目的地。
* 6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
* 7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器硬盘上
* 8.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
* 9.使用网络字节输出流FileOutputStream对象中的方法readwrite给客户端回写“上传成功”
* 10.释放资源(FileOutputStream,Socket,ServerSocket)*/
public class TCPServer {
public static void main(String[] args) throws IOException {
//* 1.创建一个服务器端ServerSocket对象,构造方法中绑定服务器的IP地址和系统要指定的端口号。
ServerSocket server = new ServerSocket(8889);
// * 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象。
/*让服务器一直处于监听状态(死循环accept方法)
* 有一个客户端上传文件,就保存一个文件*/
while (true) {
Socket socket = server.accept();
/*使用多线程技术,提高线程效率
* 有一个客户端上传文件,就开始一个线程,完成文件的上传*/
new Thread(new Runnable() {
@Override
public void run() {
try {
// * 3.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
InputStream is = socket.getInputStream();
// * 4.判断D:\\java2019_5_13\图片\\u文件夹是否存在,不存在则创建
File file = new File("D:\\java2019_5_13\\图片\\u");
if (!file.exists()) {
file.mkdirs();
}
/*自定义一个文件的命名规则————————繁殖同名的文件被覆盖
* 规则——————————————————————————域名+毫秒值+随机数*/
String fileName = "lmz" + System.currentTimeMillis() + new Random().nextInt(999999) + ".jpg";
// * 5.创建一个本地字节输入流FileOutputStream对象,构造方法中绑定要输出的目的地。
// FileOutputStream fos = new FileOutputStream(file + "\\do while.jpg");
FileOutputStream fos = new FileOutputStream(file + "\\" + fileName);
// * 6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
int len = 0;
byte[] bytes = new byte[1024];
while ((len = is.read()) != -1) {
// * 7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器硬盘上
fos.write(bytes, 0, len);
}
// * 8.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
// * 9.使用网络字节输出流FileOutputStream对象中的方法readwrite给客户端回写“上传成功”
socket.getOutputStream().write("上传成功".getBytes());
// * 10.释放资源(FileOutputStream,Socket,ServerSocket)
fos.close();
socket.close();
} catch (
IOException e)
{
System.out.println(e);
}
}
}).start();
//服务器就不用关闭了
// server.close();
}
}
}
package cn.lrf.netDemo;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/*文件上传案例的客户端————————读取本地文件,上传到服务器,读取服务器回写的数据
* 明确
* 数据源——————D:\java2019_5_13\图片\do while.jpg
* 目的地——————服务器
* 1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源。
* 2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号。
* 3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
* 4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
* 5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传服务器
* 6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
* 7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据
* 8.释放资源(FileInputStream,Socket)*/
public class TCPClient {
public static void main(String[] args) throws IOException {
//1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源。
FileInputStream fis = new FileInputStream("D:\\java2019_5_13\\图片\\do while.jpg");
//2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号。
Socket socket = new Socket("127.0.0.1", 8889);
//3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象
OutputStream os = socket.getOutputStream();
//4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件
int len = 0;
byte[] bytes = new byte[1024];
while ((len = fis.read(bytes)) != -1) {
//5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传服务器
os.write(bytes, 0, len);
}
/*解决阻塞问题————上传完文件,给服务器写一个结束标记*/
socket.shutdownOutput();
//6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象
InputStream is = socket.getInputStream();
while ((len = is.read(bytes)) != -1) {
//7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据
System.out.println(new String(bytes, 0, len));
}
//8.释放资源(FileInputStream,Socket)
fis.close();
socket.close();
}
}