步骤:
1.先创建2个Java类:服务端(Server),客户端(Client);
2.创建2个功能工具类:
DataUtil(用于实现发送接收消息以及上传下载文件)
Message(用于对消息的重写)
3.创建两个封装工具类:
ClientUtil(用于对客户端进行封装)
ServerUtil(用于对服务端进行封装)
4.运行的时候先启动服务端,再启动客户端
程序代码:
Client(客户端):
package sc;
import util.ClientUtil;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Client {
public static void main(String []args){
Client client = new Client("127.0.0.1",9999);
Socket socket = client.getSocket();
System.out.println("客户端启动------");
try {
ClientUtil.start(socket);
} catch (Exception e) {
e.printStackTrace();
}
}
Socket socket;
public Client(String ip,int port) {
try {
socket = new Socket(ip,port);
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket getSocket() {
return socket;
}
}
Server(服务端):
package sc;
import util.ServerUtil;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String []args){
Server server = new Server(9999);
Socket socket = server.acceptSocket();
System.out.println("服务端启动------");
try {
ServerUtil.start(socket);
} catch (Exception e) {
e.printStackTrace();
}
}
ServerSocket serverSocket;
//构造函数
public Server(int port) {
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket acceptSocket(){
try {
Socket socket = serverSocket.accept();
return socket;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
DataUtil(功能工具类):
package util;
import java.io.*;
import java.net.Socket;
public class DataUtil {
public static void sendMessage(Socket socket, String msg) {
try {
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
public static String receiveMessage(Socket socket) {
try {
DataInputStream dis = new DataInputStream(socket.getInputStream());
String msg = dis.readUTF();
return msg;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void sendFile(Socket socket, File file) {
//1.发送文件名
DataUtil.sendMessage(socket, file.getName());
//2.发送文件大小
DataUtil.sendMessage(socket, file.length() + "");
//3.发送文件数据
try (FileInputStream fis = new FileInputStream(file);) {
transferData(fis, socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public static File receiveFile(Socket socket) {
//1.获取文件名
String fileName = DataUtil.receiveMessage(socket);
//2.获取文件大小
int len = Integer.parseInt(DataUtil.receiveMessage(socket));
//3.获取文件数据
//fos放在try里面起到一个关流的作用
try (FileOutputStream fos = new FileOutputStream(fileName);) {
transferData(socket.getInputStream(), fos, len);
} catch (IOException e) {
e.printStackTrace();
}
//return一个文件
return new File(fileName);
}
//获取文件数据,用于send方法
public static void transferData(InputStream is, OutputStream os) {
int len = 0;
byte[] arr = new byte[1024];
try {
while ((len = is.read(arr)) != -1) {
os.write(arr, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
//获取文件数据,用于receive方法
public static void transferData(InputStream is, OutputStream os, int len) {
byte[] arr = new byte[1024];
try {
//这里使用长度大于0去判断,主要原因是关流的问题,如果用"(len=is.read(arr))!=-1"去判断,需要 socket.shutdownOutput();
//不使用长度 >0 判断,就只能传输一次文件,因为len不会读到-1,解决方法要么用多线程,要么用大于0去判断
while (len > 0) {
int read = is.read(arr);
os.write(arr, 0, read);
len -= read;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Message(工具类):
package util;
public class Message {
private String sendIP;
private String receiveIP;
private String Context;
public Message(String sendIP, String receiveIP, String context) {
this.sendIP = sendIP;
this.receiveIP = receiveIP;
Context = context;
}
public void setSendIP(String sendIP) {
this.sendIP = sendIP;
}
public void setReceiveIP(String receiveIP) {
this.receiveIP = receiveIP;
}
public void setContext(String context) {
Context = context;
}
@Override
public String toString() {
return "Message{" +
"sendIP='" + sendIP + '\'' +
", receiveIP='" + receiveIP + '\'' +
", Context='" + Context + '\'' +
'}';
}
}
ClientUtil(工具类,封装客户端):
package util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class ClientUtil {
public static void start(Socket socket) throws Exception{
System.out.println("请输入选项:");
System.out.println("0.退出\t1.发送消息\t2.接收消息\t3.发送文件\t4.接收文件");
Scanner sc = new Scanner(System.in);
OutputStream os = socket.getOutputStream();
while(true){
int n = sc.nextInt();
os.write(n);
if(n==0){
System.out.println("客户端已退出------" );
break;
}
switch (n){
case 1:
String sendIP,receiveIP,context;
System.out.println("请输入发送的ip:");
sendIP = sc.next();
System.out.println("请输入接收的ip:");
receiveIP = sc.next();
System.out.println("请输入内容:");
context = sc.next();
Message msg = new Message(sendIP,receiveIP,context);
sendMessage(socket,msg);
System.out.println("消息发送成功!");
break;
case 2:
receiveMessage(socket);
System.out.println("消息接收成功!");
break;
case 3:
//输入一个文件的地址:如d:\\1.txt
System.out.println("请输入发送的文件路径:");
String fileName = sc.next();
File file = new File(fileName);
sendFile(socket,file);
System.out.println("文件发送成功!");
break;
case 4:
receiveFile(socket);
System.out.println("文件接收成功!");
break;
default:
System.out.println("请输入合法的选项!");
}
System.out.println("请输入选项:");
System.out.println("0.退出\t1.发送消息\t2.接收消息\t3.发送文件\t4.接收文件");
}
}
public static void sendMessage(Socket socket,Message msg){
DataUtil.sendMessage(socket,msg.toString());
}
public static void receiveMessage(Socket socket){
String msg = DataUtil.receiveMessage(socket);
System.out.println(msg);
}
public static void sendFile(Socket socket, File file){
DataUtil.sendFile(socket,file);
}
public static void receiveFile(Socket socket){
File file = DataUtil.receiveFile(socket);
File path = new File("D:\\ud");
if(!path.exists())
path.mkdirs();
copyFile(file,path+"\\"+file.getName());
}
//将文件移动到指定路径,路径为:D:/ud
public static void copyFile(File file,String path){
file.renameTo(new File(path));
}
}
ServerUtil(工具类,封装服务端):
package util;
import java.io.File;
import java.io.InputStream;
import java.net.Socket;
public class ServerUtil {
public static void start(Socket socket) throws Exception{
InputStream is = socket.getInputStream();
while (true){
int n = is.read();
System.out.println("您的选择为:"+ n);
if(n==0){
System.out.println("服务端已退出------");
break;
}
switch (n){
case 1:
receiveMessage(socket);
System.out.println("服务端已接收消息!");
break;
case 2:
Message msg = new Message("1","2","3");
sendMessage(socket,msg);
System.out.println("客户端已接收消息!");
break;
case 3:
receiveFile(socket);
System.out.println("客户端文件上传成功!");
break;
case 4:
File file = new File("d:/1.txt");
sendFile(socket,file);
System.out.println("客户端已接收到文件!");
break;
default:
System.out.println("客户端输入的选项非法,请重新输入!");
}
}
}
public static void sendMessage(Socket socket,Message msg){
DataUtil.sendMessage(socket,msg.toString());
}
public static void receiveMessage(Socket socket){
String msg = DataUtil.receiveMessage(socket);
System.out.println(msg);
}
public static void sendFile(Socket socket, File file){
DataUtil.sendFile(socket,file);
}
public static void receiveFile(Socket socket){
File file = DataUtil.receiveFile(socket);
File path = new File("D:\\ud");
if(!path.exists())
path.mkdirs();
copyFile(file,path+"\\"+file.getName());
}
//将文件移动到指定路径,路径为:D:/ud
public static void copyFile(File file,String path){
file.renameTo(new File(path));
}
}
运行截图
客户端:
服务端: