java网络编程——tcp
- tcp协议
- 例1(发送一句话):
- 例2(传文件):
- 例3(改进例2):
java网络编程udp请到java网络编程之udp
tcp协议
- TCP是有链接的协议
- TCP属于一问一答
- TCP有服务器和客户端的概念
编码时:
有两个很重要的对象 :
Scoket:服务端和客户端都要使用,负责传输数据。
ServerSoket:服务端使用,负责接收客户端的连接请求。
其它两个重要的对象:
InputStream:输入流
OutputStream:输出流
例1(发送一句话):
客户端发送一句话给服务器
服务端:
public class TcpServer {
public static void main(String [] args) throws IOException {
//1. 创建服务器端Socket
ServerSocket serverSocket = new ServerSocket(2200);
// 获取客户端的连接
Socket socket = serverSocket.accept();
//2. 获取输入流,这里的流是通过socket拿到的,也属于来自网络
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
//3. 获取客户端传上来的消息
char [] message = new char[1024];
int length = 0;
if((length = inputStreamReader.read(message)) != -1) {
String str = new String(message,0,length);
System.out.println("收到客户端的消息:" + str);
}
inputStreamReader.close();
inputStream.close();
socket.close();
}
}
客户端:
public class TcpClient {
public static void main(String ... args) throws IOException {
//1. 申明客户端socket对象
Socket socketClient = new Socket("127.0.0.1",2200);
//2. 准备要发送的数据
String message = "你好,服务器,我来了!";
//3. 发送数据到服务器
//3.1 获取输出流,这里的输出流其实是网络流。回想一下我们io里的源和目标的类型
OutputStream outputStream = socketClient.getOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
//发送数据到服务器
outputStreamWriter.write(message);
//关闭流,关闭流也就关闭了和服务器的连接
outputStreamWriter.close();
socketClient.close();
System.out.println("客户端消息发送结束");
}
}
例2(传文件):
客户端给服务端上传一个图片(可以类比为io流的复制文件操作,吧文件存放位置改为另外一台电脑)
客户端:
public class TcpClient {
public static void main(String [] args) throws IOException {
System.out.println("上传客户端启动");
Socket socketClient = new Socket("127.0.0.1",2200);
//创建文件输入流
FileInputStream fileInputStream = new FileInputStream("image/4.jpg");
// 创建输出流,改输出流将把文件数据输送到服务器上
OutputStream outputStream = socketClient.getOutputStream();
int data = 0;
while((data = fileInputStream.read()) != -1) {
outputStream.write(data);
}
fileInputStream.close();
outputStream.close();
socketClient.close();
System.out.println("客户端退出链接");
}
}
服务端:
public class TcpServer {
public static void main(String [] args) throws IOException {
System.out.println("上传服务器启动");
ServerSocket serverSocket = new ServerSocket(2200);
Socket socket = serverSocket.accept();
// 创建客户端输入流,准备接收客户端上传的文件数据
InputStream inputStream = socket.getInputStream();
long currentTime = System.currentTimeMillis();
// 创建文件输入流,用于保存客户端上传的文件到服务器本地磁盘
FileOutputStream fileOutputStream = new FileOutputStream("image/" + currentTime +".jpg");
int data = 0;
// 通过输入流,读取客户端上传的文件数据
while((data = inputStream.read()) != -1) {
// 将文件数据写入到服务的本地磁盘
fileOutputStream.write(data);
}
fileOutputStream.close();
inputStream.close();
socket.close();
System.out.println("服务端接收文件完毕");
}
}
例3(改进例2):
在例2的基础上,当文件上传完后服务器发送“图片接收完”给客户端。
客户端:
public class TcpClient {
public static void main(String [] args) throws IOException {
System.out.println("上传客户端启动");
Socket socketClient = new Socket("127.0.0.1",2200);
//创建文件输入流
FileInputStream fileInputStream = new FileInputStream("image/4.jpg");
// 创建输出流,改输出流将把文件数据输送到服务器上
OutputStream outputStream = socketClient.getOutputStream();
int data = 0;
while((data = fileInputStream.read()) != -1) {
outputStream.write(data);
}
//shutdownOutput 给服务器一个结束标记,告诉服务器输出操作已经传输完毕,但socket不关闭。
// 服务器的输入流会接收到这个标记,明白数据传输已经完毕,然后退出while循环。
socketClient.shutdownOutput();
System.out.println("本地文件上传结束.. 等待服务器的响应");
// 创建一个输入流,读取服务器发送的消息
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(socketClient.getInputStream()));
String message = bufferedReader.readLine();
System.out.println("服务器说:" + message);
fileInputStream.close();
outputStream.close();
socketClient.close();
System.out.println("客户端退出链接");
}
}
shutdownOutput 给服务器一个结束标记,告诉服务器输出操作已经传输完毕,但socket不关闭。
服务器的输入流会接收到这个标记,明白数据传输已经完毕,然后退出while循环。如果没有这句代码,服务器就不知道客户端的数据传输完成,会一直在while循环中。
服务端:
public class TcpServer {
public static void main(String [] args) throws IOException {
System.out.println("上传服务器启动");
ServerSocket serverSocket = new ServerSocket(2200);
Socket socket = serverSocket.accept();
// 创建客户端输入流,准备接收客户端上传的文件数据
InputStream inputStream = socket.getInputStream();
long currentTime = System.currentTimeMillis();
// 创建文件输入流,用于保存客户端上传的文件到服务器本地磁盘
FileOutputStream fileOutputStream = new FileOutputStream("image/" + currentTime +".jpg");
int data = 0;
// 通过输入流,读取客户端上传的文件数据
while((data = inputStream.read()) != -1) {
// 将文件数据写入到服务的本地磁盘
fileOutputStream.write(data);
}
System.out.println("服务器保存文件结束,开始发送文件上传完毕的消息给客户端");
//创建一个输出流,用于向客户端输出消息
BufferedWriter bufferedWriter = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write("文件上传完毕");
bufferedWriter.close();
// 改进:文件上传完毕,给客户端发送一条消息
fileOutputStream.close();
inputStream.close();
socket.close();
System.out.println("服务端接收文件完毕");
}
}