要求
客户端向服务端传输一个文件,服务端接受文件之后将文件保存在本地,并向客户端返回 接收成功 的信息,客户端接收到信息之后将信息打印到控制台上。
分析
客户端向服务器传输文件,实质上就是将本地的文件变成文件流,然后写入到Socket
的OutputStream
中
然后服务器将OutputStream
写入到文件流中,进行保存文件的操作。
服务端向客户端返回信息,只用拿到客户端的Socket
然后把返回的信息写入OutputStream
中就可以了。
客户端接收服务端返回的信息,只需要在传输完文件之后去获取客户端Socket
的InputStream
(会一直等待服务器),然后把流里面的内容转成字符串就可以了。
注意
由于数据是在网络中传输的,服务端读取流的时候是无法while_((_len = inputStream.read_(_buffer_)) _!= -1_)_
来判断流是否结束的(本地文件可以有EOF),因此,需要我们在客户端传输数据结束之后,给服务端一个结束的信号socket.shutdownOutput_()_
代码
package test21;
import org.junit.Test;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created By Intellij IDEA
*
* @author Xinrui Yu
* @date 2021/12/5 21:10 星期日
*/
public class SocketServerTest2 {
@Test
public void client(){
Socket socket = null;
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream = null;
InputStream inputStream = null;
try{
fileInputStream = new FileInputStream("img.jpg");
bufferedInputStream = new BufferedInputStream(fileInputStream);
InetAddress ip = InetAddress.getByName("127.0.0.1");
socket = new Socket(ip,8080);
OutputStream outputStream = socket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
while((len = bufferedInputStream.read(buffer)) != -1){
outputStream.write(buffer,0,len);
}
socket.shutdownOutput();
inputStream = socket.getInputStream();
byte[] buffer2 = new byte[1024];
int len2;
while((len2 = inputStream.read(buffer2)) != -1){
String str = new String(buffer2,0,len2);
System.out.print(str);
}
}catch (IOException e){
e.printStackTrace();
}finally {
if(bufferedInputStream != null){
try {
bufferedInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
public void server(){
ServerSocket serverSocket = null;
BufferedOutputStream bufferedOutputStream = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try{
FileOutputStream fileOutputStream = new FileOutputStream("SocketImage.png");
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
serverSocket = new ServerSocket(8080);
Socket clientSocket = serverSocket.accept();
inputStream = clientSocket.getInputStream();
int len;
byte[] buffer = new byte[1024];
while((len = inputStream.read(buffer)) != -1){
bufferedOutputStream.write(buffer,0,len);
}
System.out.println("成功收到来自:" + clientSocket.getInetAddress().getHostAddress() + "的图片");
outputStream = clientSocket.getOutputStream();
outputStream.write("照片已收到!谢谢你!".getBytes());
Thread.sleep(3000);
}catch (IOException | InterruptedException e){
e.printStackTrace();
}finally {
if(bufferedOutputStream != null){
try {
bufferedOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
运行
服务端等待客户端的连接
客户端启动之后会等待服务端返回信息
服务端3s(手动设置的)之后,将返回成功的信息返回给客户端,客户端接收到信息之后打印到控制台,然后程序才会截止。