Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Server.java <=== Server
- package webSocket;
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.security.NoSuchAlgorithmException;
- import java.util.ArrayList;
- import java.util.StringTokenizer;
- public class Server {
- ArrayList<NewClient> clientArray = new ArrayList<NewClient>();
- int PORT = 4447;
- private ServerSocket serverSocket;
- private Socket clientSocket;
- public Server() throws IOException, Exception {
- serverSocket = new ServerSocket(PORT);
- System.out.println("Server Connected...");
- while (true) {
- clientSocket = serverSocket.accept(); //accept new client
- NewClient newClient = new NewClient(this, clientSocket);
- newClient.start();
- // clientArray will be added after receiving message from client
- clientArray.add(newClient);
- }
- }
- // public void broadcast(String msgFromClient) throws IOException {
- // // send message to all connected usersArray
- // synchronized (clientArray) {
- // for (NewClient newClient : clientArray) {
- // newClient.sendToMe(msgFromClient.getBytes());
- // }
- // }
- // }
- public static void main(String[] args) throws IOException, InterruptedException, NoSuchAlgorithmException, Exception {
- new Server();
- }
- }
- //NewClient.java <=== Server
- package webSocket;
- import java.io.*;
- import java.net.*;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.StringTokenizer;
- import sun.misc.BASE64Encoder;
- public class NewClient extends Thread {
- Socket clientSocket;
- Server server;
- String loginName = "";
- String loginIP = "";
- BufferedReader in;
- PrintWriter out;
- public static final int MASK_SIZE = 4;
- public static final int SINGLE_FRAME_UNMASKED = 0x81;
- public NewClient(Server server, Socket client) throws IOException {
- this.clientSocket = client;
- this.server = server;
- in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
- out = new PrintWriter(clientSocket.getOutputStream());
- if (handshake()) {
- try {
- // LOGIN
- String loginInfo = receiveMessage(); //first data from client
- // userName@/127.0.0.1 => (userName, userIP)
- StringTokenizer tok = new StringTokenizer(loginInfo, "@");
- loginName = tok.nextToken();
- String tempLogin = "Welcome " + loginName;
- sendToMe(tempLogin.getBytes());
- // new user
- if (server.clientArray.size() > 0) {
- String temp = "";
- for (NewClient newClient : server.clientArray) {
- temp += (newClient.loginName) + "@";
- }
- // send other's login info to me
- String tempUserlist = "USERLIST@" + server.clientArray.size() + "@" + temp;
- sendToMe(tempUserlist.getBytes());
- }
- // old user
- for (NewClient newClient : server.clientArray) {
- // send my login info to other
- String tempAdd = "ADD@" + loginName;
- newClient.sendToMe(tempAdd.getBytes());
- }
- } // try
- catch (Exception e) {
- System.out.println(e.getMessage());
- }
- }
- }
- public void run() {
- String msgFromClient = null;
- // msgFromClient = username@ALL@hello world
- while (true) {
- try {
- msgFromClient = receiveMessage();
- if (msgFromClient.equals("CLOSE")) {
- for (NewClient newClient : server.clientArray) {
- String tempDelete = "DELETE@" + loginName;
- newClient.sendToMe(tempDelete.getBytes());
- }
- server.clientArray.remove(this);
- in.close();
- out.close();
- clientSocket.close();
- return; // or break;
- //break;
- } else {
- // msgFromClient = username@ALL@hello world
- StringTokenizer token = new StringTokenizer(msgFromClient, "@");
- String sender = token.nextToken();
- String receiver = token.nextToken();
- String content = token.nextToken();
- for (NewClient newClient : server.clientArray) {
- if (receiver.equals("ALL")) {
- if (!sender.equals(newClient.getUserName())) {
- msgFromClient = sender + ": " + content;
- newClient.sendToMe(msgFromClient.getBytes());
- } else {
- msgFromClient = "Me" + ": " + content;
- sendToMe(msgFromClient.getBytes());
- }
- } else if (!receiver.equals("ALL")) {
- if (newClient.getUserName().equals(receiver)) {
- msgFromClient = sender + ": " + content;
- newClient.sendToMe(msgFromClient.getBytes());
- }
- }
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }// end of while
- }
- private boolean handshake() throws IOException {
- //PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
- //BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
- HashMap<String, String> keys = new HashMap<>();
- String str;
- //Reading clientSocket handshake / request from clientSocket
- while (!(str = in.readLine()).equals("")) {
- String[] s = str.split(": ");
- if (s.length == 2) {
- keys.put(s[0], s[1]);
- }
- }
- String respondingHash;
- try {
- respondingHash = new BASE64Encoder().encode(MessageDigest.getInstance("SHA-1")
- .digest((keys.get("Sec-WebSocket-Key")
- + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes()));
- } catch (NoSuchAlgorithmException ex) {
- ex.printStackTrace();
- return false;
- }
- //Write handshake / response to clientSocket
- out.write("HTTP/1.1 101 Switching Protocols\r\n"
- + "Upgrade: websocket\r\n"
- + "Connection: Upgrade\r\n"
- + "Sec-WebSocket-Accept: " + respondingHash + "\r\n"
- + "\r\n");
- out.flush();
- return true;
- }
- public void sendToMe(byte[] msg) throws IOException {
- //System.out.println("Sending to clientSocket");
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- BufferedOutputStream os = new BufferedOutputStream(clientSocket.getOutputStream());
- baos.write(SINGLE_FRAME_UNMASKED); //fisrt byte(0x81): text type
- baos.write(msg.length); //frame in second byte: text length
- baos.write(msg); //0x81 + msg length + msg
- baos.flush();
- baos.close();
- os.write(baos.toByteArray(), 0, baos.size()); //send message in bytes
- os.flush();
- }
- public String receiveMessage() throws IOException {
- byte[] buf = readBytes(2); //reading two bytes from clientSocket
- int opcode = buf[0] & 0x0F; //first byte(0x81) & 0x0F(00001111)
- if (opcode == 8) { //opcode 8 is close connection
- System.out.println("Client left!");
- for (NewClient newClient : server.clientArray) {
- String tempDelete = "DELETE@" + loginName;
- newClient.sendToMe(tempDelete.getBytes());
- }
- server.clientArray.remove(this);
- // in.close();
- // out.close();
- // clientSocket.close();
- closeCon();
- return null; // error without "return"
- } else { // opcode == 1 / first byte => text type
- //length of message text
- final int msgLength = getSizeOfMessage(buf[1]);
- buf = readBytes(MASK_SIZE + msgLength); //MASK_SIZE = 4 bytes
- // convert message(byte) to string // 4 ==> mask size 4 bytes
- buf = unMask(Arrays.copyOfRange(buf, 0, 4), Arrays.copyOfRange(buf, 4, buf.length));
- String message = new String(buf); // message in byte to String
- return message;
- }
- }
- private byte[] readBytes(int numOfBytes) throws IOException {
- byte[] b = new byte[numOfBytes];
- clientSocket.getInputStream().read(b); //message from clientSocket
- return b;
- }
- // get the length of text message
- private int getSizeOfMessage(byte b) {
- //Must subtract 0x80 from masked frames
- return ((b & 0xFF) - 0x80);
- }
- // extract only text message removing mask 4 bytes
- private byte[] unMask(byte[] mask, byte[] data) { // mask = 4 bytes
- for (int i = 0; i < data.length; i++) {
- data[i] = (byte) (data[i] ^ mask[i % mask.length]);
- }
- return data;
- }
- public String getUserName() {
- return loginName;
- }
- public void closeCon() throws IOException {
- in.close();
- out.close();
- clientSocket.close();
- return; // or break;
- }
- }
- //websocket.html <=== Client
- <!DOCTYPE HTML>
- <html>
- <body>
- Instruction;<br><br>
- LOGIN: username@ <br>
- * from server: <br>
- * welcome username<br>
- * USERLISTf@numOfUser@user, or<br>
- * ADDf@user<br><br>
- MESSAGE: username@ALL@hello wolrd <br>
- MESSAGE to receiver: username@receiver@hello receiver <br>
- * from server: <br>
- * username: hello world<br><br>
- <button type="button" onclick="connect();">Connect</button>
- <button type="button" onclick="connection.close()">Close</button>
- <form>
- <input type="text" id="msg" />
- <button type="button" onclick="sendMsg();">Send message!</button>
- <script>
- var connection;
- function connect() {
- console.log("connection");
- connection = new WebSocket("ws://localhost:4447/");
- // Log errors
- connection.onerror = function (error) {
- console.log('WebSocket Error ');
- console.log(error);
- };
- // Log messages from the server
- connection.onmessage = function (e) {
- console.log('Server: ' + e.data);
- alert(e.data);
- };
- connection.onopen = function (e) {
- console.log("Connection open...");
- alert("Connection open...");
- }
- connection.onclose = function (e) {
- console.log("Connection closed...");
- alert("Connection closed...");
- }
- }
- // end of Log messages from the server
- function sendMsg() {
- connection.send(document.getElementById("msg").value);
- }
- function close() {
- console.log("Closing...");
- connection.close();
- }
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment