1.我在想怎么说呢,其实代码是东拼拼西凑凑出来的 ? ,这好几百行代码不怎么会写,或者说勉强看懂,但如果让我一个人来写根本写不出来。这次课设基于Tcp的客户端和服务端在本地的文件传输的程序。C语言,C++也可以写,看了同学的代码基本只能放在命令行cmd里运行,不美观吧。唉,如果放在QT里会更好看(b站上看过效果很不错,加上背景图片),为了赶了交作业直接下载Idea运行代码,QT没来得及搞。
2.文件传输是各种计算机网络实现的基本功能,文件传送协议是一种最基本的应用层协议。它是按照客户/服务器的模式进行工作,提供交式的访问。是INTERNET使用最广泛的协议之一。以及深入了解计算机网络是建立在TCP/IP网络体系结构之上。本课程设计目的是要学会利用已有网络环境设计并实现简单应用层协议,掌握TCP/IP网络应用程序基本设计方法各实现技巧。并要求使用这些功能实现一个简单的文件传送协议。
3.需求分析:计算机网络是建立在TCP/IP网络体系结构之上,计算机除了安装TCP/IP软件外,还安装了TCP/IP开发系统。实验室各计算机具备了windows环境中套接字Socket的编程接口功能。可为用户提供全网范围的进程通信功能。本实验要求利用这些功能,设计和实现一个简单的文件传输协议。
4.可行性分析:根据实现过程分析其可行性。当程序中客户请求连接时,服务器将会向客户发送一条消息告知其IP地址,请求添加一个用户。然关闭连接并继续接收端口的连接。建立各个命令功能对应的函数,发送请求,等待服务器的服务。服务器端初始化WinSock.创建SOCKET,获取主机信息,并对客户端进行会话,发送回复讯息给客户端。响应完毕后关闭连接,释放winSock. 从而实现文件传输。
5.实现文件的传送,需用Socket编程接口写两个程序,分别为客户端(Client.cs)和服务端(Server.cs)。客户端程序为文件接收端、服务器端为文件发送端。接收端能将收到的文件保存到机器上,从而实现文件传输能功。
6.这次实践课最后计网老师给的分数有点虚高,95分,唉, ? 恐怕也是我在学校四年里最好的一次了。
代码如下:
服务端server:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
public class Server {
public static void main(String[] args) {
int port = 1230; #服务器端口
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Server started. Listening on port " + port);
while (true) {
Socket socket = serverSocket.accept(); #服务器地址
System.out.println("Client " + socket.getRemoteSocketAddress() + " connected!");
new Thread(new ClientHandler(socket)).start();
}
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
private static class ClientHandler implements Runnable {
private Socket socket;
private DataOutputStream dos;
private DataInputStream dis;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
while (true) {
String request = dis.readUTF();
if (request.equals("UPLOAD")) {
String fileName = dis.readUTF(); #上传文件
receiveFile(fileName);
} else if (request.equals("DOWNLOAD")) {
String fileName = dis.readUTF();
sendFile(fileName);
} else if (request.equals("GET_FILE_LIST")) {
sendFileList();
} else {
break;
}
}
System.out.println("Client " + socket.getRemoteSocketAddress() + " disconnected!");
socket.close();
} catch (IOException e) {
System.out.println("Error: " + e.getMessage());
}
}
private void receiveFile(String fileName) {
try {
long fileSize = dis.readLong();
FileOutputStream fos = new FileOutputStream(fileName);
byte[] buffer = new byte[4096];
int read;
long remaining = fileSize;
while ((read = dis.read(buffer, 0, (int) Math.min(buffer.length, remaining))) > 0) {
remaining -= read;
fos.write(buffer, 0, read);
}
fos.close();
System.out.println("File received: " + fileName);
} catch (IOException e) {
System.out.println("Error receiving file: " + e.getMessage());
}
}
private void sendFile(String fileName) {
try {
File file = new File(fileName);
if (!file.exists()) {
dos.writeUTF("FILE_NOT_FOUND");
return;
}
dos.writeUTF(file.getName());
dos.writeLong(file.length());
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
int read;
while ((read = fis.read(buffer)) != -1) {
dos.write(buffer, 0, read);
}
fis.close();
System.out.println("File sent: " + fileName);
} catch (IOException e) {
System.out.println("Error sending file: " + e.getMessage());
}
}
private void sendFileList() {
try {
List<String> fileList = Files.list(Paths.get("."))
.filter(Files::isRegularFile)
.map(Path::getFileName)
.map(Path::toString)
.collect(Collectors.toList());
dos.writeInt(fileList.size());
for (String file : fileList) {
dos.writeUTF(file);
}
} catch (IOException e) {
System.out.println("Error sending file list: " + e.getMessage());
}
}
}
}
客户端client:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Client {
private JFrame frame;
private JTextField textFieldServerIP;
private JTextField textFieldServerPort;
private JTextField textFieldDownloadPath;
private JButton btnConnect;
private JButton btnUpload;
private JButton btnDownload;
private Socket socket;
private DataOutputStream dos;
private DataInputStream dis;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Client window = new Client();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Client() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
textFieldServerIP = new JTextField();
textFieldServerIP.setBounds(128, 36, 114, 19);
frame.getContentPane().add(textFieldServerIP);
textFieldServerIP.setColumns(10);
JLabel lblServerIp = new JLabel("Server IP:");
lblServerIp.setBounds(58, 38, 70, 15);
frame.getContentPane().add(lblServerIp);
textFieldServerPort = new JTextField();
textFieldServerPort.setBounds(128, 67, 114, 19);
frame.getContentPane().add(textFieldServerPort);
textFieldServerPort.setColumns(10);
JLabel lblServerPort = new JLabel("Server Port:");
lblServerPort.setBounds(41, 69, 87, 15);
frame.getContentPane().add(lblServerPort);
btnConnect = new JButton("Connect");
btnConnect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
socket = new Socket(textFieldServerIP.getText(), Integer.parseInt(textFieldServerPort.getText()));
dos = new DataOutputStream(socket.getOutputStream());
dis = new DataInputStream(socket.getInputStream());
JOptionPane.showMessageDialog(null, "Connected to server!");
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error connecting to server: " + ex.getMessage());
}
}
});
btnConnect.setBounds(254, 36, 117, 50);
frame.getContentPane().add(btnConnect);
btnUpload = new JButton("Upload");
btnUpload.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
int returnValue = fileChooser.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
try {
dos.writeUTF("UPLOAD");
dos.writeUTF(selectedFile.getName());
dos.writeLong(selectedFile.length());
FileInputStream fis = new FileInputStream(selectedFile);
byte[] buffer = new byte[4096];
int read;
while ((read = fis.read(buffer)) != -1) {
dos.write(buffer, 0, read);
}
fis.close();
JOptionPane.showMessageDialog(null, "File uploaded successfully!");
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error uploading file: " + ex.getMessage());
}
}
}
});
btnUpload.setBounds(128, 166, 117, 25);
frame.getContentPane().add(btnUpload);
btnDownload = new JButton("Download");
btnDownload.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
dos.writeUTF("GET_FILE_LIST");
int fileListSize = dis.readInt();
List<String> fileList = new ArrayList<>();
for (int i = 0; i < fileListSize; i++) {
fileList.add(dis.readUTF());
}
if (fileList.isEmpty()) {
JOptionPane.showMessageDialog(null, "No files available on the server!");
return;
}
String[] fileListArray = fileList.toArray(new String[0]);
String selectedFile = (String) JOptionPane.showInputDialog(null, "Select a file to download:",
"Download", JOptionPane.QUESTION_MESSAGE, null, fileListArray, fileListArray[0]);
if (selectedFile == null) {
return;
}
dos.writeUTF("DOWNLOAD");
dos.writeUTF(selectedFile);
String fileName = dis.readUTF();
long fileSize = dis.readLong();
JFileChooser fileChooser = new JFileChooser();
fileChooser.setSelectedFile(new File(fileName));
fileChooser.setCurrentDirectory(new File(textFieldDownloadPath.getText()));
int returnValue = fileChooser.showSaveDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File saveFile = fileChooser.getSelectedFile();
FileOutputStream fos = new FileOutputStream(saveFile);
byte[] buffer = new byte[4096];
int read;
long remaining = fileSize;
while ((read = dis.read(buffer, 0, (int) Math.min(buffer.length, remaining))) > 0) {
remaining -= read;
fos.write(buffer, 0, read);
}
fos.close();
JOptionPane.showMessageDialog(null, "File downloaded successfully!");
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error downloading file: " + ex.getMessage());
}
}
});
btnDownload.setBounds(254, 166, 117, 25);
frame.getContentPane().add(btnDownload);
textFieldDownloadPath = new JTextField();
textFieldDownloadPath.setBounds(128, 98, 243, 19);
frame.getContentPane().add(textFieldDownloadPath);
textFieldDownloadPath.setColumns(10);
JLabel lblDownloadPath = new JLabel("Download Path:");
lblDownloadPath.setBounds(28, 100, 104, 15);
frame.getContentPane().add(lblDownloadPath);
}
}
由于是本机上传和下载文件,所以代码里ip地址就是127.0.0.1,不用改,本机回环地址;端口port可以随便设置。后面我想起nginx,npm,可以localhost:port(端口自己设置),可以本地打开网页。
下面是IDEA运行结果:
评论 (0)