具有消息(文本)和文件传输的 Java Socket 多用户聊天应用程序
Posted
技术标签:
【中文标题】具有消息(文本)和文件传输的 Java Socket 多用户聊天应用程序【英文标题】:Java Socket Multi user chat app with both message (text) and file transfer 【发布时间】:2021-12-22 02:45:22 【问题描述】:我是 Java 新手。我正在通过制作一个聊天应用程序来学习套接字和线程编程,其中从客户端发送的消息将被服务器接收,服务器会将其发送给另一个客户端。
服务器是这样工作的。字符串的第一个单词是命令,其余是参数。
发消息的命令 示例:味精 jony 嗨!
这将发送嗨!给客户名字 jony。 //
login tom tom123 // 将使用用户名“tom”和密码“tom123”登录 tom
现在我想添加文件传输。所以一个客户端可以将文件发送到另一个客户端。据我所知,我需要使用 DataInputStream 。在这种情况下,如何让服务器区分以下程序中的文件和文本?或者我可以像“file jony c://abc.txt”一样将 abc.txt 文件发送给 jony?
已编辑:看起来像 handleFile 被调用,但它什么都没有。 (如果像handfleFile()一样在开始时调用hangle文件,它就可以工作;
我做错了什么:(
这是我的服务器代码的一部分。
private void handleClientSocket() throws IOException, InterruptedException, SQLException
// InputStream inputStream = clientSocket.getInputStream();
// this.outputStream = clientSocket.getOutputStream();
// DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream());
this.outputStream = new DataOutputStream(clientSocket.getOutputStream());
this.inputStream = new DataInputStream(clientSocket.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
Connect(); //Connects to databse
// handleFile();
while ( (line = reader.readLine()) != null)
String[] tokens = StringUtils.split(line);
if (tokens != null && tokens.length > 0)
String cmd = tokens[0];
if ("quit".equalsIgnoreCase(cmd) || "logoff".equalsIgnoreCase(cmd))
handleLogOff();
break;
else if ("login".equalsIgnoreCase(cmd))
handleLogin(outputStream, tokens);
else if ("msg".equalsIgnoreCase(cmd))
String[] tokenMsg = StringUtils.split(line, null, 3);
handleMessage(tokenMsg);
else if ("join".equalsIgnoreCase(cmd))
handleJoin(tokens);
else if ("leave".equalsIgnoreCase(cmd))
handleLeave(tokens);
else if ("signup".equalsIgnoreCase(cmd))
handleSignUp(tokens);
else if ("create".equalsIgnoreCase(cmd))
handleCreateGroup(tokens);
else if ("sendFile".equalsIgnoreCase(cmd))
// inputStream.close();
handleFile();
else
String msg = "Unknown command: " + cmd + "\n";
outputStream.write(msg.getBytes());
private void handleFile ()
System.out.println("File handler called");
try
System.out.println("File handler called");
// DataInputStream input = new DataInputStream(clientSocket.getInputStream());
DataInputStream inputStream = new DataInputStream(clientSocket.getInputStream());
int fileNameLength = inputStream.readInt();
System.out.println(fileNameLength);
if (fileNameLength > 0)
byte[] fileNameBytes = new byte[fileNameLength];
inputStream.readFully(fileNameBytes, 0, fileNameBytes.length);
String fileName = new String(fileNameBytes);
System.out.println(fileName);
int fileContentLength = inputStream.readInt();
System.out.println(fileContentLength);
if (fileContentLength > 0)
byte[] fileContentBytes = new byte[fileContentLength];
inputStream.readFully(fileContentBytes, 0, fileContentBytes.length);
System.out.println(fileContentBytes);
// File fileToDownload = new File(fileName);
FileOutputStream fileOutputStream = new FileOutputStream("D:\\bbb.txt");
fileOutputStream.write(fileContentBytes);
fileOutputStream.close();
这是客户端代码:
public class Main
public static void main(String[] args)
Scanner scanner = new Scanner(System.in);
// final File[] fileToSend = new File[1];
// fileToSend[0] = "C:\\Users\\alvyi\\Downloads";
File file = new File("D:\\aaa.txt");
try
Socket socket = new Socket("localhost", 6000);
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
while(true)
System.out.println("In the Loop");
dataOutputStream.write("login alvy alvy\n".getBytes(StandardCharsets.UTF_8));
dataOutputStream.write("sendFile\n".getBytes(StandardCharsets.UTF_8));
FileInputStream fileInputStream = new FileInputStream(file.getAbsolutePath());
String fileName = file.getName();
// Convert the name of the file into an array of bytes to be sent to the server.
byte[] fileNameBytes = fileName.getBytes();
// Create a byte array the size of the file so don't send too little or too much data to the server.
byte[] fileBytes = new byte[(int)file.length()];
// Put the contents of the file into the array of bytes to be sent so these bytes can be sent to the server.
fileInputStream.read(fileBytes);
// Send the length of the name of the file so server knows when to stop reading.
dataOutputStream.writeInt(50);
dataOutputStream.writeInt(fileNameBytes.length);
// Send the file name.
dataOutputStream.write(fileNameBytes);
// Send the length of the byte array so the server knows when to stop reading.
dataOutputStream.writeInt(fileBytes.length);
// Send the actual file.
dataOutputStream.write(fileBytes);
String echoString = scanner.nextLine();
// System.out.println(inputStream.readLine());
// outputStream.write("sendFile".getBytes());
catch (IOException e)
e.printStackTrace();
【问题讨论】:
【参考方案1】:在这种情况下,如何让服务器区分以下程序中的文件和文本?或者我可以像“file jony c://abc.txt”一样将 abc.txt 文件发送给 jony?
从可用性的角度来看,将send file
命令作为聊天 API 中的单独命令是有意义的。因此,添加一个不同的命令来使用像file
这样的描述性名称的想法是有意义的。
如果要谈API的实现,那么这就是标准问题的标准解决方案。
这里是code,它解释了如何通过套接字发送文件。
【讨论】:
是的,我这样做了,但看起来它什么也没做。但是,如果我在开始时调用该方法(当前已评论),它会起作用!!!我现在头疼:/ 那为什么不一开始就调用呢? 那会破坏整个目的。我只想在客户端发送命令 sendFile 时发送文件。如果我一开始就使用它,那么我每次都需要发送一个文件,然后才能开始做其他事情。我已经更新了代码。如果可能的话,请看一下:( 谢谢,终于明白了 BufferReader 导致了所有问题。使用 inputStream.readLine() 解决了这个问题。 (家庭它不会在未来引起问题哈哈) 如果我的回答对您有所帮助,请随时将答案标记为已接受并点赞以上是关于具有消息(文本)和文件传输的 Java Socket 多用户聊天应用程序的主要内容,如果未能解决你的问题,请参考以下文章