commit
551ac9b1bd
@ -0,0 +1,33 @@ |
|||||||
|
HELP.md |
||||||
|
target/ |
||||||
|
!.mvn/wrapper/maven-wrapper.jar |
||||||
|
!**/src/main/**/target/ |
||||||
|
!**/src/test/**/target/ |
||||||
|
|
||||||
|
### STS ### |
||||||
|
.apt_generated |
||||||
|
.classpath |
||||||
|
.factorypath |
||||||
|
.project |
||||||
|
.settings |
||||||
|
.springBeans |
||||||
|
.sts4-cache |
||||||
|
|
||||||
|
### IntelliJ IDEA ### |
||||||
|
.idea |
||||||
|
*.iws |
||||||
|
*.iml |
||||||
|
*.ipr |
||||||
|
|
||||||
|
### NetBeans ### |
||||||
|
/nbproject/private/ |
||||||
|
/nbbuild/ |
||||||
|
/dist/ |
||||||
|
/nbdist/ |
||||||
|
/.nb-gradle/ |
||||||
|
build/ |
||||||
|
!**/src/main/**/build/ |
||||||
|
!**/src/test/**/build/ |
||||||
|
|
||||||
|
### VS Code ### |
||||||
|
.vscode/ |
@ -0,0 +1,20 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>net.lensfrex</groupId> |
||||||
|
<artifactId>lesson</artifactId> |
||||||
|
<version>1.0-SNAPSHOT</version> |
||||||
|
</parent> |
||||||
|
|
||||||
|
<artifactId>exp1-oop</artifactId> |
||||||
|
|
||||||
|
<properties> |
||||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||||
|
</properties> |
||||||
|
|
||||||
|
</project> |
@ -0,0 +1,30 @@ |
|||||||
|
package net.lensfrex; |
||||||
|
|
||||||
|
public class AbstractExtends { |
||||||
|
protected void run() { |
||||||
|
Father father = new Child(); |
||||||
|
|
||||||
|
father.method1(); |
||||||
|
father.method2(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
abstract class Father { |
||||||
|
public abstract void method1(); |
||||||
|
|
||||||
|
public abstract void method2(); |
||||||
|
} |
||||||
|
|
||||||
|
// -------------------------------------------
|
||||||
|
class Child extends Father { |
||||||
|
@Override |
||||||
|
public void method1() { |
||||||
|
System.out.println("Do some thing in method1"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void method2() { |
||||||
|
System.out.println("Do some thing in method2"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
package net.lensfrex; |
||||||
|
|
||||||
|
public class Interface { |
||||||
|
protected void run() { |
||||||
|
AnInterface anInterface = new AnInterface() { |
||||||
|
@Override |
||||||
|
public void method1() { |
||||||
|
System.out.println("Do some thing in method1"); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void method2() { |
||||||
|
System.out.println("Do some thing in method2"); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
anInterface.method1(); |
||||||
|
anInterface.method2(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
interface AnInterface { |
||||||
|
void method1(); |
||||||
|
|
||||||
|
void method2(); |
||||||
|
} |
@ -0,0 +1,51 @@ |
|||||||
|
package net.lensfrex; |
||||||
|
|
||||||
|
import java.io.BufferedReader; |
||||||
|
import java.io.InputStreamReader; |
||||||
|
|
||||||
|
public class Main { |
||||||
|
public static void main(String[] args) throws Exception { |
||||||
|
if (args.length > 0) { |
||||||
|
execute(args[0]); |
||||||
|
} else { |
||||||
|
System.out.println("Witch to run? (1, 2, 3)"); |
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); |
||||||
|
|
||||||
|
execute(reader.readLine()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void execute(String option) { |
||||||
|
Main main = new Main(); |
||||||
|
|
||||||
|
switch (option) { |
||||||
|
case "1": |
||||||
|
main.run1(); |
||||||
|
break; |
||||||
|
case "2": |
||||||
|
main.run2(); |
||||||
|
break; |
||||||
|
case "3": |
||||||
|
main.run3(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
System.out.printf("Invalid input for '%s'%n", option); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void run1() { |
||||||
|
Rectangle rectangle = new Rectangle(3, 4); |
||||||
|
|
||||||
|
System.out.println("rectangleHeight: " + rectangle.getHeight()); |
||||||
|
System.out.println("rectangleWidth: " + rectangle.getWidth()); |
||||||
|
System.out.println("rectangleSize: " + rectangle.getSize()); |
||||||
|
} |
||||||
|
|
||||||
|
private void run2() { |
||||||
|
new Interface().run(); |
||||||
|
} |
||||||
|
|
||||||
|
private void run3() { |
||||||
|
new AbstractExtends().run(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,33 @@ |
|||||||
|
package net.lensfrex; |
||||||
|
|
||||||
|
public class Rectangle { |
||||||
|
private float height = 0; |
||||||
|
private float width = 0; |
||||||
|
|
||||||
|
public Rectangle() {} |
||||||
|
|
||||||
|
public Rectangle(float height, float width) { |
||||||
|
this.height = height; |
||||||
|
this.width = width; |
||||||
|
} |
||||||
|
|
||||||
|
public float getSize() { |
||||||
|
return height * width; |
||||||
|
} |
||||||
|
|
||||||
|
public float getHeight() { |
||||||
|
return height; |
||||||
|
} |
||||||
|
|
||||||
|
public void setHeight(float height) { |
||||||
|
this.height = height; |
||||||
|
} |
||||||
|
|
||||||
|
public float getWidth() { |
||||||
|
return width; |
||||||
|
} |
||||||
|
|
||||||
|
public void setWidth(float width) { |
||||||
|
this.width = width; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>net.lensfrex</groupId> |
||||||
|
<artifactId>lesson</artifactId> |
||||||
|
<version>1.0-SNAPSHOT</version> |
||||||
|
</parent> |
||||||
|
|
||||||
|
<artifactId>exp2-thread</artifactId> |
||||||
|
|
||||||
|
<properties> |
||||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||||
|
</properties> |
||||||
|
|
||||||
|
</project> |
@ -0,0 +1,42 @@ |
|||||||
|
package net.lensfrex; |
||||||
|
|
||||||
|
import java.io.BufferedReader; |
||||||
|
import java.io.InputStreamReader; |
||||||
|
|
||||||
|
public class Main { |
||||||
|
public static void main(String[] args) throws Exception { |
||||||
|
System.out.println("Thread Lesson report"); |
||||||
|
|
||||||
|
if (args.length > 0) { |
||||||
|
execute(args[0]); |
||||||
|
} else { |
||||||
|
System.out.println("Witch to run? (1, 2)"); |
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); |
||||||
|
|
||||||
|
execute(reader.readLine()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void execute(String option) { |
||||||
|
Main main = new Main(); |
||||||
|
|
||||||
|
switch (option) { |
||||||
|
case "1": |
||||||
|
main.run1(); |
||||||
|
break; |
||||||
|
case "2": |
||||||
|
main.run2(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
System.out.printf("Invalid input for '%s'%n", option); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void run1() { |
||||||
|
new RabbitAndTortoise().runTest(); |
||||||
|
} |
||||||
|
|
||||||
|
private void run2() { |
||||||
|
new Ticket().runTest(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
package net.lensfrex; |
||||||
|
|
||||||
|
public class RabbitAndTortoise { |
||||||
|
public void runTest() { |
||||||
|
Animal rabbit = new Animal("Rabbit", 16, 32); |
||||||
|
Animal tortoise = new Animal("Tortoise", 8, 32); |
||||||
|
|
||||||
|
new Thread(rabbit).start(); |
||||||
|
new Thread(tortoise).start(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class Animal implements Runnable { |
||||||
|
private final String name; |
||||||
|
|
||||||
|
private final int speed; |
||||||
|
private final int targetDistance; |
||||||
|
|
||||||
|
private int totalDistance = 0; |
||||||
|
|
||||||
|
public Animal(String name, int speed, int targetDistance) { |
||||||
|
this.name = name; |
||||||
|
this.speed = speed; |
||||||
|
this.targetDistance = targetDistance; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
while (totalDistance <= targetDistance) { |
||||||
|
try { |
||||||
|
Thread.sleep((int) (Math.random() * 1000) + 500); |
||||||
|
} catch (Exception ignored) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
totalDistance += speed; |
||||||
|
System.out.printf("[%s] has run %d%n", name, totalDistance); |
||||||
|
} |
||||||
|
|
||||||
|
System.out.printf("[%s] has finish the game.%n", name); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package net.lensfrex; |
||||||
|
|
||||||
|
public class Ticket { |
||||||
|
public void runTest() { |
||||||
|
TicketOffice ticketOffice = new TicketOffice(); |
||||||
|
new Thread(ticketOffice, "0").start(); |
||||||
|
new Thread(ticketOffice, "1").start(); |
||||||
|
new Thread(ticketOffice, "2").start(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class TicketOffice implements Runnable { |
||||||
|
private static int ticket = 8; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
String name = Thread.currentThread().getName(); |
||||||
|
while(sellTicket(name)); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean sellTicket(String name) { |
||||||
|
synchronized (this) { |
||||||
|
if (ticket <= 0) { |
||||||
|
System.out.printf("[%s]: Ticket was sold out.%n", name); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
System.out.printf("TicketOffice '%s' is selling ticket No.%s%n", name, ticket); |
||||||
|
ticket--; |
||||||
|
|
||||||
|
try { |
||||||
|
Thread.sleep(128); |
||||||
|
} catch (Exception ignored) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>net.lensfrex</groupId> |
||||||
|
<artifactId>lesson</artifactId> |
||||||
|
<version>1.0-SNAPSHOT</version> |
||||||
|
</parent> |
||||||
|
|
||||||
|
<artifactId>exp3-network</artifactId> |
||||||
|
|
||||||
|
<properties> |
||||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||||
|
</properties> |
||||||
|
<build> |
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<groupId>org.apache.maven.plugins</groupId> |
||||||
|
<artifactId>maven-compiler-plugin</artifactId> |
||||||
|
<configuration> |
||||||
|
<source>9</source> |
||||||
|
<target>9</target> |
||||||
|
</configuration> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
|
||||||
|
</project> |
@ -0,0 +1,54 @@ |
|||||||
|
package net.lensfrex; |
||||||
|
|
||||||
|
import javafx.application.Application; |
||||||
|
import net.lensfrex.socket.Client; |
||||||
|
import net.lensfrex.socket.Server; |
||||||
|
import net.lensfrex.socket.Util; |
||||||
|
|
||||||
|
import java.io.BufferedReader; |
||||||
|
import java.io.InputStreamReader; |
||||||
|
|
||||||
|
public class Main { |
||||||
|
public static void main(String[] args) throws Exception { |
||||||
|
System.out.println("Thread Lesson report"); |
||||||
|
|
||||||
|
if (args.length > 0) { |
||||||
|
execute(args[0]); |
||||||
|
} else { |
||||||
|
System.out.println("Witch to run? (1server, 1client, 2)"); |
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); |
||||||
|
|
||||||
|
execute(reader.readLine()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void execute(String option) { |
||||||
|
Main main = new Main(); |
||||||
|
|
||||||
|
switch (option) { |
||||||
|
case "1server": |
||||||
|
main.run1Server(); |
||||||
|
break; |
||||||
|
case "1client": |
||||||
|
main.run1Client(); |
||||||
|
break; |
||||||
|
case "2": |
||||||
|
main.run2(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
System.out.printf("Invalid input for '%s'%n", option); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void run1Server() { |
||||||
|
new Server().start(); |
||||||
|
} |
||||||
|
|
||||||
|
private void run1Client() { |
||||||
|
new Client().start(); |
||||||
|
} |
||||||
|
|
||||||
|
private void run2() { |
||||||
|
System.out.println(Util.randomString(128)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
import javafx.application.Application; |
||||||
|
import javafx.stage.Stage; |
||||||
|
|
||||||
|
public class Client extends Application { |
||||||
|
public void start() { |
||||||
|
launch(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void start(Stage primaryStage) throws Exception { |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
|
||||||
|
public class Constant { |
||||||
|
public static final byte[] MAGIC_HEADER = "AETH".getBytes(StandardCharsets.UTF_8); |
||||||
|
|
||||||
|
public static final int OPCODE_LENGTH = 4; |
||||||
|
public static final byte[] OPCODE_REQUEST_MESSAGE = "RMSG".getBytes(StandardCharsets.UTF_8); |
||||||
|
public static final byte[] OPCODE_SEND_MESSAGE = "SMSG".getBytes(StandardCharsets.UTF_8); |
||||||
|
public static final byte[] OPCODE_ONLINE = "ONLI".getBytes(StandardCharsets.UTF_8); |
||||||
|
public static final byte[] OPCODE_OFFLINE = "OFFL".getBytes(StandardCharsets.UTF_8); |
||||||
|
|
||||||
|
public static final byte[] MESSAGE_OK = "OK".getBytes(StandardCharsets.UTF_8); |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
public class Data implements Serializable { |
||||||
|
// private final byte[] data
|
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
public class DataPack implements Serializable { |
||||||
|
private final byte[] opcode; |
||||||
|
private final int dataLength; |
||||||
|
private final byte[] data; |
||||||
|
|
||||||
|
public DataPack(byte[] opcode, byte[] data) { |
||||||
|
this.opcode = opcode; |
||||||
|
this.dataLength = data.length; |
||||||
|
this.data = data; |
||||||
|
} |
||||||
|
|
||||||
|
public byte[] getOpcode() { |
||||||
|
return opcode; |
||||||
|
} |
||||||
|
|
||||||
|
public int getDataLength() { |
||||||
|
return dataLength; |
||||||
|
} |
||||||
|
|
||||||
|
public byte[] getData() { |
||||||
|
return data; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
public class MessageData { |
||||||
|
private final int idLength; |
||||||
|
private final byte[] idData; |
||||||
|
|
||||||
|
private final int messageLength; |
||||||
|
private final byte[] messageData; |
||||||
|
|
||||||
|
public MessageData(int idLength, byte[] idData, int messageLength, byte[] messageData) { |
||||||
|
this.idLength = idLength; |
||||||
|
this.idData = idData; |
||||||
|
this.messageLength = messageLength; |
||||||
|
this.messageData = messageData; |
||||||
|
} |
||||||
|
|
||||||
|
public int getIdLength() { |
||||||
|
return idLength; |
||||||
|
} |
||||||
|
|
||||||
|
public byte[] getIdData() { |
||||||
|
return idData; |
||||||
|
} |
||||||
|
|
||||||
|
public int getMessageLength() { |
||||||
|
return messageLength; |
||||||
|
} |
||||||
|
|
||||||
|
public byte[] getMessageData() { |
||||||
|
return messageData; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
public class Request { |
||||||
|
|
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
import java.io.Serializable; |
||||||
|
|
||||||
|
public class RequestBody implements Serializable { |
||||||
|
} |
@ -0,0 +1,158 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
import java.io.*; |
||||||
|
import java.net.ServerSocket; |
||||||
|
import java.net.Socket; |
||||||
|
import java.nio.charset.StandardCharsets; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.HashSet; |
||||||
|
|
||||||
|
public class Server { |
||||||
|
private static boolean stop = false; |
||||||
|
|
||||||
|
public void start() { |
||||||
|
Server.stop = false; |
||||||
|
|
||||||
|
try (ServerSocket serverSocket = new ServerSocket(2333)) { |
||||||
|
while (!stop) { |
||||||
|
// Start a new thread to service more than one client
|
||||||
|
new ServerThread(serverSocket.accept()).start(); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
System.err.println("Some exception happened: " + e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void stop() { |
||||||
|
Server.stop = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class ServerThread extends Thread { |
||||||
|
private static final HashSet<User> onlineUsers = new HashSet(); |
||||||
|
|
||||||
|
private final Socket socket; |
||||||
|
|
||||||
|
public ServerThread(Socket socket) { |
||||||
|
this.socket = socket; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
try (InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream()) { |
||||||
|
byte[] clientMagicHeader = new byte[Constant.MAGIC_HEADER.length]; |
||||||
|
if (inputStream.read(clientMagicHeader) == -1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (!Arrays.equals(clientMagicHeader, Constant.MAGIC_HEADER)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
byte[] clientOpcode = new byte[Constant.OPCODE_LENGTH]; |
||||||
|
if (inputStream.read(clientOpcode) == -1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
int dataLength = getLengthField(inputStream); |
||||||
|
if (dataLength == -1) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
this.executeAction(clientOpcode, dataLength, inputStream, outputStream); |
||||||
|
} catch (IOException e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void executeAction(byte[] opcode, int dataLength, InputStream inputStream, OutputStream outputStream) throws IOException { |
||||||
|
byte[] data = this.readRequest(dataLength, inputStream); |
||||||
|
|
||||||
|
if (Arrays.equals(Constant.OPCODE_ONLINE, opcode)) { |
||||||
|
this.login(new String(data)); |
||||||
|
this.sendResponse(Constant.MESSAGE_OK, outputStream); |
||||||
|
} else if (Arrays.equals(Constant.OPCODE_OFFLINE, opcode)) { |
||||||
|
this.logout(new String(data)); |
||||||
|
} else if (Arrays.equals(Constant.OPCODE_REQUEST_MESSAGE, opcode)) { |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void login(String id) { |
||||||
|
User user = new User(id); |
||||||
|
onlineUsers.add(user); |
||||||
|
|
||||||
|
System.out.printf("User '%s' login.%n", user.getId()); |
||||||
|
} |
||||||
|
|
||||||
|
private void logout(String id) { |
||||||
|
User user = new User(id); |
||||||
|
onlineUsers.add(user); |
||||||
|
System.out.printf("User '%s' logout.%n", user.getId()); |
||||||
|
} |
||||||
|
|
||||||
|
private void |
||||||
|
|
||||||
|
private int sendMessage(User user, OutputStream outputStream) throws IOException { |
||||||
|
if (!onlineUsers.contains(user)) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
int responseLength = this.sendResponse(Util.randomString(128), outputStream); |
||||||
|
|
||||||
|
return responseLength; |
||||||
|
} |
||||||
|
|
||||||
|
private int getLengthField(InputStream inputStream) throws IOException { |
||||||
|
byte[] tmp = new byte[4]; |
||||||
|
if (inputStream.read(tmp) == -1) { |
||||||
|
return -1; |
||||||
|
} |
||||||
|
|
||||||
|
return Util.bytesToInt32(tmp); |
||||||
|
} |
||||||
|
|
||||||
|
private void receiveMessage(DataPack dataPack) { |
||||||
|
byte[] data = dataPack.getData(); |
||||||
|
|
||||||
|
User user = new User(); |
||||||
|
|
||||||
|
String message = new String(data); |
||||||
|
System.out.printf("Receive message '%s' from: '%s'%n", user.getId(), message); |
||||||
|
System.out.println("----------------"); |
||||||
|
} |
||||||
|
|
||||||
|
private DataPack readRequest(InputStream inputStream) throws IOException { |
||||||
|
byte[] clientOpcode = new byte[Constant.OPCODE_LENGTH]; |
||||||
|
if (inputStream.read(clientOpcode) == -1) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
int dataLength = this.getLengthField(inputStream); |
||||||
|
|
||||||
|
byte[] data = new byte[dataLength]; |
||||||
|
inputStream.read(data); |
||||||
|
|
||||||
|
return new DataPack(clientOpcode, data); |
||||||
|
} |
||||||
|
|
||||||
|
private int sendResponse(String message, OutputStream outputStream) throws IOException { |
||||||
|
return this.sendResponse(message.getBytes(StandardCharsets.UTF_8), outputStream); |
||||||
|
} |
||||||
|
|
||||||
|
private int sendResponse(byte[] data, OutputStream outputStream) throws IOException { |
||||||
|
DataPack dataPack = new DataPack(Constant.OPCODE_SEND_MESSAGE, data); |
||||||
|
|
||||||
|
return this.sendResponse(dataPack, outputStream); |
||||||
|
} |
||||||
|
|
||||||
|
private int sendResponse(DataPack dataPack, OutputStream outputStream) throws IOException { |
||||||
|
outputStream.write(Constant.MAGIC_HEADER); |
||||||
|
outputStream.write(dataPack.getOpcode()); |
||||||
|
|
||||||
|
outputStream.write(Util.int32ToBytes(dataPack.getDataLength())); |
||||||
|
outputStream.write(dataPack.getData()); |
||||||
|
|
||||||
|
return dataPack.getDataLength(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
public class User { |
||||||
|
private final String id; |
||||||
|
|
||||||
|
public User(String id) { |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
|
||||||
|
public String getId() { |
||||||
|
return id; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
package net.lensfrex.socket; |
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.util.Random; |
||||||
|
|
||||||
|
public class Util { |
||||||
|
private static final char[] alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray(); |
||||||
|
private static final Random random = new Random(); |
||||||
|
|
||||||
|
public static String randomString(int length) { |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
for (int i = 0; i < length; i++) { |
||||||
|
sb.append(alphabet[random.nextInt(alphabet.length)]); |
||||||
|
} |
||||||
|
|
||||||
|
return sb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
public static int bytesToInt32(byte[] bytes) { |
||||||
|
int result = 0; |
||||||
|
for (int i = 0; i < 4; i++) { |
||||||
|
int shift = (3 - i) * 8; |
||||||
|
result += (bytes[i] & 0xFF) << shift; |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
public static byte[] int32ToBytes(int i) { |
||||||
|
byte[] result = new byte[4]; |
||||||
|
result[0] = (byte) ((i >> 24) & 0xFF); |
||||||
|
result[1] = (byte) ((i >> 16) & 0xFF); |
||||||
|
result[2] = (byte) ((i >> 8) & 0xFF); |
||||||
|
result[3] = (byte) (i & 0xFF); |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
public static byte[] readAllData(InputStream inputStream) { |
||||||
|
return readAllData(inputStream, 5);// read every 5kb in default
|
||||||
|
} |
||||||
|
|
||||||
|
public static byte[] readAllData(InputStream inputStream, int byteAllocation) { |
||||||
|
// On Java 9 and newer version, can be more simply:
|
||||||
|
// try (ByteArrayOutputStream byteArrayInputStream = new ByteArrayOutputStream(); inputStream) {
|
||||||
|
|
||||||
|
try (ByteArrayOutputStream byteArrayInputStream = new ByteArrayOutputStream()) { |
||||||
|
byte[] bytes = new byte[1024 * byteAllocation]; |
||||||
|
|
||||||
|
for (int length; (length = inputStream.read(bytes)) != -1; ) { |
||||||
|
byteArrayInputStream.write(bytes, 0, length); |
||||||
|
} |
||||||
|
|
||||||
|
byteArrayInputStream.flush(); |
||||||
|
|
||||||
|
return byteArrayInputStream.toByteArray(); |
||||||
|
} catch (Exception e) { |
||||||
|
e.printStackTrace(); |
||||||
|
return null; |
||||||
|
} finally { |
||||||
|
try { |
||||||
|
inputStream.close(); |
||||||
|
} catch (IOException ignored) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
|
||||||
|
<groupId>net.lensfrex</groupId> |
||||||
|
<artifactId>lesson</artifactId> |
||||||
|
<version>1.0-SNAPSHOT</version> |
||||||
|
<packaging>pom</packaging> |
||||||
|
<modules> |
||||||
|
<module>exp1-oop</module> |
||||||
|
<module>exp2-thread</module> |
||||||
|
<module>exp3-network</module> |
||||||
|
</modules> |
||||||
|
|
||||||
|
<properties> |
||||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||||
|
</properties> |
||||||
|
|
||||||
|
</project> |
@ -0,0 +1,7 @@ |
|||||||
|
package net.lensfrex; |
||||||
|
|
||||||
|
public class Main { |
||||||
|
public static void main(String[] args) { |
||||||
|
System.out.println("Hello world!"); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue