La idea general: 1. Servidor: Multiproceso para aceptar el cliente. El clienthandler implementa la interfaz Runnable y se construye con parámetros y el parámetro es Socket. El método run de clienthandler bloquea la lectura del mensaje del cliente y juzga el tipo de mensaje y realiza un juicio. Si es chat, el servidor devuelve un mensaje del cliente. Si es archivo, un nuevo subproceso pasará el nombre de archivo y la longitud del archivo para aceptar el archivo. 2. Cliente: El cliente supervisa la entrada de la consola, y el formato de entrada es mess: + información o archivo: la ruta absoluta del archivo de origen. La clase interna liunnablestener hereda Runnable para escuchar los mensajes devueltos por el servidor.
Paquete de terceros: paquete XStream. (Si su jdk es mayor que 1.8, es mejor utilizar la versión superior del paquete, la versión inferior no es adecuada para expresiones lmbda)
1. Código y función de clase: conversión de formato
public class ProtocalObj {
/**
* Generate xml
*
* @return
*/
public String toXML() {
XStream x = new XStream();
// Set the alias, the default is the full path name of the class
x.alias(getClass().getSimpleName(), getClass());
String xml = x.toXML(this);// Convert this class to xml and return
return xml;
}
/**
* xml-->Entity class
*
* @param xml
* @return
*/
public Object fromXML(String xml) {
XStream x = new XStream();
x.alias(getClass().getSimpleName(), getClass());
return x.fromXML(xml);
}
}
2. Código de clase y función: heredar la clase de conversión de formato, implementar la interfaz Serializable, clase de interacción de datos cliente-servidor
public class Message extends ProtocalObj implements Serializable {
private static final long serialVersionUID = 1L;
private String content;
private int type;
private long fileLength;
private String fileName;
public Message(int type, long fileLength, String fileName) {
this.type = type;
this.fileLength = fileLength;
this.fileName = fileName;
}
public Message(String content, int type) {
this.content = content;
this.type = type;
}
public Message() {
}
public Message(int type) {
this.type = type;
}
public String getContent() {
return this.content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toXML() {
return super.toXML();
}
@Override
public Object fromXML(String xml) {
return super.fromXML(xml);
}
public int getType() {
return this.type;
}
public void setType(int type) {
this.type = type;
}
public long getFileLength() {
return fileLength;
}
public void setFileLength(long fileLength) {
this.fileLength = fileLength;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
3. Código y función de clase:
//Information type class, used to represent the information type class
public class MessageType {
public static final int MSG_TYPE_CHAT= 604;
public static final int MES_TYPE_FILE = 800;
public MessageType() {
}
}
4. Código y función de clase: clase de inicio del lado servidor
public class Server {
// Program entry class
// public static ClientManager manager = new ClientManager();
//Server program entry method
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(9999);
System.out.println("Server Start");
//Continuously accept the client with an infinite loop
while(true) {
Socket client = server.accept();
(new Thread(new ClientHandler(client))).start();
}
} catch (IOException var3) {
var3.printStackTrace();
}
}
}
5. Código y función de clase: clase de procesamiento del lado servidor
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//Server processing thread
public class ClientHandler implements Runnable {
private Socket client;
private DataOutputStream out;
private DataInputStream in;
//The construction method accepts a socket
public ClientHandler(Socket client) {
this.client = client;
try {
this.in = new DataInputStream(client.getInputStream());
this.out = new DataOutputStream(client.getOutputStream());
} catch (IOException var3) {
var3.printStackTrace();
}
}
//Process the message from the user, determine the message type and perform the corresponding operation
public void run() {
try {
String xml = null;
Message message = null;
// Block reading client information
while (true) {
while ((xml = this.in.readUTF()) != null) {
message = new Message();
message = (Message) message.fromXML(xml);
System.out.println(message.toXML());
switch (message.getType()){
// to chat with
case MessageType.MSG_TYPE_CHAT:
reply(message);
break;
// file transfer
case MessageType.MES_TYPE_FILE:
new Thread(new FileReceive(message.getFileName(),message.getFileLength())).start();
}
}
}
} catch (IOException var6) {
var6.printStackTrace();
}
}
//Return to the corresponding client
public void reply(Message message) {
try {
System.out.println("The client said:"+message.getContent());
this.out.writeUTF(message.toXML());
System.out.println("The server said:"+message.getContent());
this.out.flush();
} catch (IOException var3) {
var3.printStackTrace();
}
}
// File receiving thread, create a new ServerSocket, monitor the specified interface 10000; accept client information
class FileReceive implements Runnable{
private ServerSocket serverSocket;
private Socket socket;
private DataInputStream in;
private String fileName;
private long fileLength;
public FileReceive( String fileName, long fileLength) {
try {
serverSocket=new ServerSocket(10000);
socket=serverSocket.accept();
in=new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
this.fileName = fileName;
this.fileLength = fileLength;
}
@Override
public void run() {
try {
FileOutputStream out=new FileOutputStream(new File("D:\"+fileName));
byte[] bytes=new byte[1024*1024];
while (in.read(bytes)!=-1){
out.write(bytes);
out.flush();
System.out.println("File transfer completed!");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6. Códigos y funciones de clase
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class client {
private static String content;
private static Socket socket;
private static DataOutputStream out;
private static DataInputStream in;
public static void main(String[] args) throws IOException {
socket = new Socket("localhost", 9999);
Scanner scanner = new Scanner(System.in);
// keyboard monitor console input
while (keyBoardListener(scanner)) {
new Thread(new Listener(socket)).start();
}
}
// keyboard monitor
private static boolean keyBoardListener(Scanner scanner) {
if (scanner.hasNext()) {
content = scanner.next();
if (content.equals("exit")) {
System.out.print("Program Exit");
return false;
} else {
// Determine the input content
if (content.startsWith("mess:")) {
String s=content.substring(5);
Message message = new Message(s, MessageType.MSG_TYPE_CHAT);
// Send information to the server
System.out.println("Information---->");
send(message);
} else if (content.startsWith("file:")) {
// Intercept the characters starting from the fifth digit
File file=new File(content.substring(5));
Message message = new Message( MessageType.MES_TYPE_FILE,file.length(),file.getName());
send(message);
send(file);
} else {
System.out.println("Please enter the correct format! message: or file: content or file address!");
}
System.out.println("You enter:" + content);
return true;
}
}
return true;
}
// send Message
private static void send(Message message) {
try {
out = new DataOutputStream(socket.getOutputStream());
out.writeUTF(message.toXML());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
// Send files in multiple threads
private static void send(File file) {
new Thread(new Runnable() {
@Override
public void run() {
byte[] bytes = new byte[1024];
try {
Socket socket=new Socket("localhost",10000);
FileInputStream inputStream = new FileInputStream(file);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
while (inputStream.read(bytes) != -1) {
out.write(bytes);
}
inputStream.close();
out.flush();
// out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
//Multi-threaded, listen for messages returned by the server
static class Listener implements Runnable {
private Socket socket;
private DataInputStream in;
public Listener(Socket socket) {
this.socket = socket;
try {
in = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String xml = null;
Message message = new Message();
while (true) {
try {
while ((xml=in.readUTF())!=null){
message=(Message)message.fromXML(xml);
switch (message.getType()){
case MessageType.MSG_TYPE_CHAT:
System.out.println("The server said:"+message.getContent());
break;
case MessageType.MES_TYPE_FILE:
System.out.println("Sent successfully!");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
.