TCP文件传输
服务器端
package com.mzq.upload;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author 孟志强
* @version 1.0
* 服务端
*/
public class TCPFileUploadServer {
public static void main(String[] args) throws Exception {
//1.监听端口8888
ServerSocket serverSocket = new ServerSocket(8888);
//2.等待连接
Socket socket = serverSocket.accept();
//3.创建一个输入流,接收客户端的数据
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
//4.用StreamUtils.streamToByteArray得到传过来文件字节数组
byte[] bytes = StreamUtils.streamToByteArray(bis);
//5.创建一个输出字节流,把文件写入到src目录下
String destFilePath = "src\\2.jpg";
BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(destFilePath));
outputStream.write(bytes);
// outputStream.flush();
// socket.shutdownOutput();//这里不用关闭
//6.告诉客户端收到图片,创建一个输出流,这里我用字符流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write("服务端收到图片");
bufferedWriter.flush();
socket.shutdownOutput();
//关闭流
bufferedWriter.close();
outputStream.close();
bis.close();
socket.close();
serverSocket.close();
}
}
客户端
package com.mzq.upload;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* @author 孟志强
* @version 1.0
* 客户端
*/
public class TCPFileUploadClient {
public static void main(String[] args) throws Exception {
//1.连接服务端
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
//2.创建一个输入字节流
String filePath = "d:\\1.jpg";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
//通过StreamUtils.streamToByteArray获取得到文件字节数组
byte[] bytes = StreamUtils.streamToByteArray(bis);
//3.创建一个输出流,传文件到服务端
BufferedOutputStream outputStream = new BufferedOutputStream(socket.getOutputStream());
outputStream.write(bytes);
outputStream.flush();
socket.shutdownOutput();
//4.接收服务端的消息
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] bytes1 = new char[1024];
int read = 0;
while ((read = bufferedReader.read(bytes1))!=-1){
System.out.println(new String(bytes1,0,read));
}
//关闭流
bufferedReader.close();
outputStream.close();
bis.close();
socket.close();
}
}
StreamUtils类
package com.mzq.upload;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 此类用于演示关于流的读写方法
*
*/
public class StreamUtils {
/**
* 功能:将输入流转换成byte[], 即可以把文件的内容读入到byte[]
* @param is
* @return
* @throws Exception
*/
public static byte[] streamToByteArray(InputStream is) throws Exception{
ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象
byte[] b = new byte[1024];//字节数组
int len;
while((len=is.read(b))!=-1){//循环读取
bos.write(b, 0, len);//把读取到的数据,写入bos
}
byte[] array = bos.toByteArray();//然后将bos 转成字节数组
bos.close();
return array;
}
/**
* 功能:将InputStream转换成String
* @param is
* @return
* @throws Exception
*/
public static String streamToString(InputStream is) throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder= new StringBuilder();
String line;
while((line=reader.readLine())!=null){
builder.append(line+"\r\n");
}
return builder.toString();
}
}
netstat指令
- netstat -an可以查看当前主机网络情况,包括端口监听情况和网络连接情况
- netstat -an | more可以分页显示
- 要求在dos控制台下执行win+r
说明:
- Listening表示某个端口在监听
- 如果有一个外部程序(客户端)连接到该端口,就会显示一条连接信息
- 输入 ctrl +c指令即可退出
指令基本使用
在文件上传代码基础上,选一个相对较大的文件上传
当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是TCP/IP来分配的,是不确定的,是随机的.
启动服务器,用netstat -an | more指令可以查看到8888端口正在被监听:
启动客户端,上传文件:
即可看到服务端和客户端交互端口及地址