将 html5 客户端与 Java 中的服务器一起使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12702305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
using html5 client with a server in java
提问by Hemant Metalia
HTML5 client reduce prograamers effort by providing client in html5 websocket client. It will be beneficial to many programmers to learn how to use this html5 websocket client with server in java.
HTML5 客户端通过在 html5 websocket 客户端中提供客户端来减少程序员的工作量。许多程序员学习如何在java中使用这个带有服务器的html5 websocket客户端将是有益的。
i want to create an Example of HTML5 clientcommunicating with a java server, but i am not able to find out the way how to do it. can anyone throw a light on it ?
我想创建一个与 Java 服务器通信的HTML5 客户端示例,但我无法找到如何执行此操作的方法。任何人都可以点亮它吗?
Reference : demo html5 client/server with c++
I have found a demo on http://java.dzone.com/articles/creating-websocket-chatbut its not working for me..
我在http://java.dzone.com/articles/creating-websocket-chat上找到了一个演示,但它对我不起作用..
回答by Andak
I've implemented a simplejava server side example which we can take a look at. I'm starting off by creating a ServerSocket which listens for a connection on port 2005
我已经实现了一个简单的java 服务器端示例,我们可以看看。我首先创建一个侦听端口 2005 上的连接的 ServerSocket
public class WebsocketServer {
public static final int MASK_SIZE = 4;
public static final int SINGLE_FRAME_UNMASKED = 0x81;
private ServerSocket serverSocket;
private Socket socket;
public WebsocketServer() throws IOException {
serverSocket = new ServerSocket(2005);
connect();
}
private void connect() throws IOException {
System.out.println("Listening");
socket = serverSocket.accept();
System.out.println("Got connection");
if(handshake()) {
listenerThread();
}
}
As defined in the RFC standard for the websocket protocol, when a client connects through a websocket, a handshakemust be done. So let's take a look at the handshake() method, it's pretty ugly so will walk stepwise through it: The first part reads the client handshake.
正如RFC 标准中定义的 websocket 协议,当客户端通过 websocket 连接时,必须进行握手。那么让我们来看看handshake() 方法,它非常难看,所以将逐步完成它: 第一部分读取客户端握手。
private boolean handshake() throws IOException {
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//This hashmap will be used to store the information given to the server in the handshake
HashMap<String, String> keys = new HashMap<>();
String str;
//Reading client handshake, handshake ends with CRLF which is again specified in the RFC, so we keep on reading until we hit ""...
while (!(str = in.readLine()).equals("")) {
//Split the string and store it in our hashmap
String[] s = str.split(": ");
System.out.println(str);
if (s.length == 2) {
keys.put(s[0], s[1]);
}
}
The client handshake looks something like this (this is what chrome gave me, version 22.0.1229.94 m), according to the RFC - section 1.2!
根据 RFC - 1.2 节,客户端握手看起来像这样(这是 chrome 给我的,版本 22.0.1229.94 m)!
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost:2005
Origin: null
Sec-WebSocket-Key: PyvrecP0EoFwVnHwC72ecA==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
Now we can use the keys-map to create a corresponding response in the handshake process. Quoting from the RFC:
现在我们可以使用keys-map在握手过程中创建相应的响应。引用RFC:
To prove that the handshake was received, the server has to take two pieces of information and combine them to form a response. The first piece of information comes from the |Sec-WebSocket-Key| header field in the client handshake. For this header field, the server has to take the value and concatenate this with the Globally Unique Identifier, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" in string form, which is unlikely to be used by network endpoints that do not understand the WebSocket Protocol. A SHA-1 hash (160 bits) , base64-encoded, of this concatenation is then returned in the server's handshake.
为了证明握手已收到,服务器必须获取两条信息并将它们组合以形成响应。第一条信息来自|Sec-WebSocket-Key| 客户端握手中的头字段。对于此标头字段,服务器必须采用该值并将其与字符串形式的全局唯一标识符“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”连接起来,不理解的网络端点不太可能使用它网络套接字协议。然后在服务器的握手中返回此串联的 SHA-1 哈希(160 位)、base64 编码。
So that's what we have to do! concatenate Sec-WebSocket-Key with a magic string, hash it with the SHA-1 hash function, and Base64-encode it. This is what the next ugly one-liner does.
所以这就是我们必须做的!将 Sec-WebSocket-Key 与魔法字符串连接起来,使用 SHA-1 哈希函数对其进行哈希处理,然后对其进行 Base64 编码。这就是下一个丑陋的单线所做的。
String hash;
try {
hash = 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;
}
Then we just return the expected response with the newly hash created into the "Sec-WebSocket-Accept" field.
然后我们只返回带有新创建的哈希的预期响应到“Sec-WebSocket-Accept”字段中。
//Write handshake response
out.write("HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: " + hash + "\r\n"
+ "\r\n");
out.flush();
return true;
}
}
We have now established a successfully websocket connection between the client and the server. So, what now? How do we make them talk to each other? We can start by sending a message from server to client. NB! We do from this point on, not talk to the client with HTTP anymore. Now we must communicate sending pure bytes, and interpret incoming bytes. So how do we do this?
我们现在已经成功地在客户端和服务器之间建立了一个 websocket 连接。所以现在怎么办?我们如何让他们互相交谈?我们可以从从服务器向客户端发送消息开始。注意!从现在开始,我们不再使用 HTTP 与客户端通信。现在我们必须通信发送纯字节,并解释传入的字节。那么我们如何做到这一点呢?
A message from the server have to be in a certain format called "frames", as spesified in the RFC - section 5.6. When sending a message from the server, the RFC states that the first byte must specify what kind of frame it is. A byte with value 0x81 tells the client that we are sending a "single-frame unmasked text message", which basically is - a text message. The suqsequent byte must represent the length of the message. Following this is the data, or payload. Well, okay... let's implement that!
来自服务器的消息必须采用称为“帧”的特定格式,如 RFC - 第 5.6 节中所述。当从服务器发送消息时,RFC 声明第一个字节必须指定它是什么类型的帧。值为 0x81 的字节告诉客户端我们正在发送“单帧未屏蔽文本消息”,它基本上是 - 文本消息。后续字节必须表示消息的长度。接下来是数据或有效载荷。好吧,好吧……让我们实现它!
public void sendMessage(byte[] msg) throws IOException {
System.out.println("Sending to client");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream os = new BufferedOutputStream(socket.getOutputStream());
//first byte is kind of frame
baos.write(SINGLE_FRAME_UNMASKED);
//Next byte is length of payload
baos.write(msg.length);
//Then goes the message
baos.write(msg);
baos.flush();
baos.close();
//This function only prints the byte representation of the frame in hex to console
convertAndPrint(baos.toByteArray());
//Send the frame to the client
os.write(baos.toByteArray(), 0, baos.size());
os.flush();
}
So to send a message to the client, we simply call sendMessage("Hello, client!".getBytes()).
所以要向客户端发送消息,我们只需调用 sendMessage("Hello, client!".getBytes())。
That wasn't too hard? What about recieving messages from the client? Well, it's a little more complicated, but hang in there!
那是不是太难了?从客户端接收消息怎么样?好吧,这有点复杂,但请坚持下去!
The frame sendt from the client is almoststructured the same way as the frame sendt from the server. First byte is type of message, and second byte is payload length. Then there is a difference: the next four bytes represents a mask. What's a mask, and why is messages from the client masked, but the servers messages not? From the RFC - section 5.1, we can see that:
从客户端发送的帧的结构几乎与从服务器发送的帧相同。第一个字节是消息类型,第二个字节是有效载荷长度。然后有一个区别:接下来的四个字节代表一个掩码。什么是掩码,为什么来自客户端的消息被掩码,而服务器消息没有?从 RFC - 5.1 节,我们可以看到:
...a client MUST mask all frames that it sends to the server... A server MUST NOT mask any frames that it sends to the client.
...客户端必须屏蔽它发送到服务器的所有帧...服务器不得屏蔽它发送到客户端的任何帧。
So the easy answer is: we just HAVE to. Well why do we have to, you may ask? Didn't I tell you to read the RFC?
所以简单的答案是:我们只需要这样做。你可能会问,为什么我们必须这样做?我不是告诉你阅读RFC吗?
Moving on, after the four byte mask in the frame, the maskedpayload is following on. And one more thing, the client must set the 9th leftmost bit in the frame to 1, to tell the server that the message is masked (Check out the neat ASCII-art frame in the RFC - section 5.2). The 9th leftmost bit corresponds to our leftmost bit in our second byte, but hey, that's our payload length byte! This means that all messages from our client will have a payload length byte equal 0b10000000 = 0x80 + the actual payload length. So to find out the real payload length, we must subtract 0x80, or 128, or 0b10000000 (or any other number system you may prefer) from the payload length byte, our second byte in the frame.
继续,在帧中的四字节掩码之后,被掩码的有效载荷紧随其后。还有一件事,客户端必须将帧中最左边的第 9 位设置为 1,以告诉服务器消息被屏蔽(查看 RFC 中的整洁 ASCII-art 帧 - 第 5.2 节)。最左边的第 9 位对应于我们第二个字节中最左边的位,但是,嘿,那是我们的有效载荷长度字节!这意味着来自我们客户端的所有消息的有效载荷长度字节等于 0b10000000 = 0x80 + 实际有效载荷长度。因此,要找出真正的有效负载长度,我们必须从有效负载长度字节(帧中的第二个字节)中减去 0x80、128 或 0b10000000(或您可能喜欢的任何其他数字系统)。
Wow, okay.. that sounds complicated... For you "TLDR"-guys, summary: subtract 0x80 from the second byte to get the payload length...
哇,好吧..听起来很复杂......对于“TLDR”-伙计们,总结:从第二个字节中减去0x80以获得有效载荷长度......
public String reiceveMessage() throws IOException {
//Read the first two bytes of the message, the frame type byte - and the payload length byte
byte[] buf = readBytes(2);
System.out.println("Headers:");
//Print them in nice hex to console
convertAndPrint(buf);
//And it with 00001111 to get four lower bits only, which is the opcode
int opcode = buf[0] & 0x0F;
//Opcode 8 is close connection
if (opcode == 8) {
//Client want to close connection!
System.out.println("Client closed!");
socket.close();
System.exit(0);
return null;
}
//Else I just assume it's a single framed text message (opcode 1)
else {
final int payloadSize = getSizeOfPayload(buf[1]);
System.out.println("Payloadsize: " + payloadSize);
//Read the mask, which is 4 bytes, and than the payload
buf = readBytes(MASK_SIZE + payloadSize);
System.out.println("Payload:");
convertAndPrint(buf);
//method continues below!
Now that we have read the whole message, it's time to unmask it so we can make some sense of the payload. To unmask it I've made a method which takes the mask, and the payload as arguments, and return the decoded payload. So the call is done with:
现在我们已经阅读了整条消息,现在是时候揭开它的掩码,这样我们就可以了解有效载荷了。为了取消屏蔽,我创建了一个方法,该方法将掩码和有效负载作为参数,并返回解码后的有效负载。所以调用完成:
buf = unMask(Arrays.copyOfRange(buf, 0, 4), Arrays.copyOfRange(buf, 4, buf.length));
String message = new String(buf);
return message;
}
}
Now the unMask method is rather sweet and tiny
现在 unMask 方法相当甜蜜和微小
private byte[] unMask(byte[] mask, byte[] data) {
for (int i = 0; i < data.length; i++) {
data[i] = (byte) (data[i] ^ mask[i % mask.length]);
}
return data;
}
Same goes for getSizeOfPayload:
getSizeOfPayload 也是如此:
private int getSizeOfPayload(byte b) {
//Must subtract 0x80 from (unsigned) masked frames
return ((b & 0xFF) - 0x80);
}
That's all! You should now be able to communicate in both directions using pure sockets. I will add the complete Java-class for the sake of completeness. It is capable of recieveing and sending messages with a client using websockets.
就这样!您现在应该能够使用纯套接字在两个方向上进行通信。为了完整起见,我将添加完整的 Java 类。它能够使用 websockets 与客户端接收和发送消息。
package javaapplication5;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import sun.misc.BASE64Encoder;
/**
*
* @author
* Anders
*/
public class WebsocketServer {
public static final int MASK_SIZE = 4;
public static final int SINGLE_FRAME_UNMASKED = 0x81;
private ServerSocket serverSocket;
private Socket socket;
public WebsocketServer() throws IOException {
serverSocket = new ServerSocket(2005);
connect();
}
private void connect() throws IOException {
System.out.println("Listening");
socket = serverSocket.accept();
System.out.println("Got connection");
if(handshake()) {
listenerThread();
}
}
private boolean handshake() throws IOException {
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
HashMap<String, String> keys = new HashMap<>();
String str;
//Reading client handshake
while (!(str = in.readLine()).equals("")) {
String[] s = str.split(": ");
System.out.println();
System.out.println(str);
if (s.length == 2) {
keys.put(s[0], s[1]);
}
}
//Do what you want with the keys here, we will just use "Sec-WebSocket-Key"
String hash;
try {
hash = 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
out.write("HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: " + hash + "\r\n"
+ "\r\n");
out.flush();
return true;
}
private byte[] readBytes(int numOfBytes) throws IOException {
byte[] b = new byte[numOfBytes];
socket.getInputStream().read(b);
return b;
}
public void sendMessage(byte[] msg) throws IOException {
System.out.println("Sending to client");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream os = new BufferedOutputStream(socket.getOutputStream());
baos.write(SINGLE_FRAME_UNMASKED);
baos.write(msg.length);
baos.write(msg);
baos.flush();
baos.close();
convertAndPrint(baos.toByteArray());
os.write(baos.toByteArray(), 0, baos.size());
os.flush();
}
public void listenerThread() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
System.out.println("Recieved from client: " + reiceveMessage());
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
t.start();
}
public String reiceveMessage() throws IOException {
byte[] buf = readBytes(2);
System.out.println("Headers:");
convertAndPrint(buf);
int opcode = buf[0] & 0x0F;
if (opcode == 8) {
//Client want to close connection!
System.out.println("Client closed!");
socket.close();
System.exit(0);
return null;
} else {
final int payloadSize = getSizeOfPayload(buf[1]);
System.out.println("Payloadsize: " + payloadSize);
buf = readBytes(MASK_SIZE + payloadSize);
System.out.println("Payload:");
convertAndPrint(buf);
buf = unMask(Arrays.copyOfRange(buf, 0, 4), Arrays.copyOfRange(buf, 4, buf.length));
String message = new String(buf);
return message;
}
}
private int getSizeOfPayload(byte b) {
//Must subtract 0x80 from masked frames
return ((b & 0xFF) - 0x80);
}
private byte[] unMask(byte[] mask, byte[] data) {
for (int i = 0; i < data.length; i++) {
data[i] = (byte) (data[i] ^ mask[i % mask.length]);
}
return data;
}
private void convertAndPrint(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X ", b));
}
System.out.println(sb.toString());
}
public static void main(String[] args) throws IOException, InterruptedException, NoSuchAlgorithmException {
WebsocketServer j = new WebsocketServer();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("Write something to the client!");
j.sendMessage(br.readLine().getBytes());
}
}
}
And a simple client in html:
和一个简单的 html 客户端:
<!DOCTYPE HTML>
<html>
<body>
<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="sayHello();">Say Hello!</button>
<script>
var connection;
function connect() {
console.log("connection");
connection = new WebSocket("ws://localhost:2005/");
// 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("Server said: " + e.data);
};
connection.onopen = function (e) {
console.log("Connection open...");
}
connection.onclose = function (e) {
console.log("Connection closed...");
}
}
function sayHello() {
connection.send(document.getElementById("msg").value);
}
function close() {
console.log("Closing...");
connection.close();
}
</script>
</body>
</html>
Hope that this will clear something up, and that I threw some light on it :)
希望这会澄清一些事情,并且我对此有所了解:)
回答by Ilya
Use jQuery ajax requests from client side, and rest services on server side.
Here about creating of war module with Rest Service
客户端使用 jQuery ajax 请求,服务端服务。
这里是关于使用 Rest Service 创建War模块
here abour jQuery ajax
这里关于 jQuery ajax
To write Java socket server, all that you need is create main program with
要编写 Java 套接字服务器,您只需要创建主程序
try
{
final ServerSocket ss = new ServerSocket(8001);
while (true)
{
final Socket s = ss.accept();
// @todo s.getInputStream();
}
}
catch (final IOException ex)
{
//
}
it's main cascade of server part
它是服务器部分的主要级联
回答by Tinman
Try reading this blog. It covers how to achieve your work using spring framework. Full support should be added soon, if not already added.
尝试阅读此博客。它涵盖了如何使用 spring 框架来完成你的工作。如果尚未添加,应尽快添加全面支持。
http://keaplogik.blogspot.com.au/2012/05/atmosphere-websockets-comet-with-spring.html?m=1
http://keaplogik.blogspot.com.au/2012/05/atmosphere-websockets-comet-with-spring.html?m=1
I'd also suggest checking the spring release notes.
我还建议检查春季发行说明。
回答by Timofey Gorshkov
You are running GlassFish. Web sockets are not enabled by default in it. To enable them you must execute the following single-line command on your domain:
您正在运行 GlassFish。默认情况下,其中未启用 Web 套接字。要启用它们,您必须在您的域上执行以下单行命令:
asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.websockets-support-enabled=true
HttpServlet.init(...)
method is called by the servlet container to indicate to a servlet that the servlet is being placed into service.*So, your log message there doesn't represent the truth.
HttpServlet.init(...)
方法由 servlet 容器调用,以向 servlet 指示该 servlet 正被置于服务中。*因此,您的日志消息并不代表事实。
回答by Mehdi Karamosly
You can also achieve that using existing framework like : jWebsocket
您还可以使用现有框架来实现,例如:jWebsocket
回答by user3101886
This is the same code above only it allows you to receive messages from the client that are above the 126 bytes. Many web socket source codes have not figure out fragmentation.
这与上面的代码相同,只是它允许您从客户端接收超过 126 字节的消息。很多web socket源代码都没有搞清楚碎片。
// Modified code from Anders, - Christopher Price
package GoodExample;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import sun.misc.BASE64Encoder;
public class JfragWS {
public static final int MASK_SIZE = 4;
public static final int SINGLE_FRAME_UNMASKED = 0x81;
private ServerSocket serverSocket;
private Socket socket;
public JfragWS() throws IOException {
serverSocket = new ServerSocket(1337);
connect();
}
private void connect() throws IOException {
System.out.println("Listening");
socket = serverSocket.accept();
System.out.println("Got connection");
if(handshake()) {
listenerThread();
}
}
private boolean handshake() throws IOException {
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
HashMap<String, String> keys = new HashMap<>();
String str;
//Reading client handshake
while (!(str = in.readLine()).equals("")) {
String[] s = str.split(": ");
System.out.println();
System.out.println(str);
if (s.length == 2) {
keys.put(s[0], s[1]);
}
}
//Do what you want with the keys here, we will just use "Sec-WebSocket-Key"
String hash;
try {
hash = 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
out.write("HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: " + hash + "\r\n"
+ "Origin: http://face2fame.com\r\n"
+ "\r\n");
out.flush();
return true;
}
private byte[] readBytes(int numOfBytes) throws IOException {
byte[] b = new byte[numOfBytes];
socket.getInputStream().read(b);
return b;
}
public void sendMessage(byte[] msg) throws IOException {
System.out.println("Sending to client");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream os = new BufferedOutputStream(socket.getOutputStream());
baos.write(SINGLE_FRAME_UNMASKED);
baos.write(msg.length);
baos.write(msg);
baos.flush();
baos.close();
convertAndPrint(baos.toByteArray());
os.write(baos.toByteArray(), 0, baos.size());
os.flush();
}
public void listenerThread() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
System.out.println("Recieved from client: " + reiceveMessage());
System.out.println("Enter data to send");
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
t.start();
}
public String reiceveMessage() throws IOException {
String EasyBytes = null;
byte[] buf = readBytes(2); // our initial header
convertAndPrint(buf);
//System.exit(0);
EasyBytes = (String.format("%02X ", buf[1]));
int payloadadder = 0;
if (EasyBytes.contains("FE")){ // Indicates extended message
byte[] buf2 = readBytes(1);
int a = (buf2[0] & 0xff) + 1; // if byte is zero there is one extra fragment so add 1!
System.out.println("Number of extra bytes" + a);
payloadadder = 2; // account for original header size
byte[] adder = null;
//String MagnificentString = "";
for (int x = 0; x < a; x++){
if(x==0){
adder = readBytes(1);
//MagnificentString += String.format("%02X ", adder[0]);
payloadadder += ((adder[0] & 0xFF) - 0x80);}
if(x==1){
payloadadder = (buf[1] & 0xFF) + (adder[0] & 0xFF);
}
if(x>1){
payloadadder = (Integer.parseInt((String.format("%02X", buf2[0]) + String.format("%02X", adder[0])), 16));
//System.out.println(String.format("%02X", buf2[0]) + String.format("%02X", adder[0]));
}
}
System.out.println("Overflow in byte/s " + payloadadder);
//System.out.println("Our Hex String " + MagnificentString);
//System.exit(0);
}
//convertAndPrint(buf);
//dont use this byte[] buf2 = readBytes(4);
System.out.println("Headers:");
//convertAndPrint(buf2);// Check out the byte sizes
int opcode = buf[0] & 0x0F;
if (opcode == 8) {
//Client want to close connection!
System.out.println("Client closed!");
socket.close();
System.exit(0);
return null;
} else {
int payloadSize = 0;
if (payloadadder <= 0){
payloadSize = getSizeOfPayload(buf[1]);}
else {
payloadSize = getSizeOfPayload(buf[1]) + payloadadder;
}
// if (extendedsize>=126){
//payloadSize = extendedsize;}
System.out.println("Payloadsize: " + payloadSize);
buf = readBytes(MASK_SIZE + payloadSize);
System.out.println("Payload:");
convertAndPrint(buf);
buf = unMask(Arrays.copyOfRange(buf, 0, 4), Arrays.copyOfRange(buf, 4, buf.length));
String message = new String(buf);
return message;
}
}
private int getSizeOfPayload(byte b) {
//Must subtract 0x80 from masked frames
int a = b & 0xff;
//System.out.println("PAYLOAD SIZE INT" + a);
return ((b & 0xFF) - 0x80);
}
private byte[] unMask(byte[] mask, byte[] data) {
for (int i = 0; i < data.length; i++) {
data[i] = (byte) (data[i] ^ mask[i % mask.length]);
}
return data;
}
private boolean convertAndPrintHeader(byte[] bytes) {
StringBuilder sb = new StringBuilder();
String CaryOverDetection = new String();
// We must test byte 2 specifically for this. In the next step we add length bytes perhaps?
//for(int i = 0; i < bytes.length; i++) {
//}
for (byte b : bytes) {
CaryOverDetection = (String.format("%02X ", b));
if (CaryOverDetection.contains("FE")){
return false;
}
sb.append(String.format("%02X ", b));
}
System.out.println(sb.toString());
return true;
}
private void convertAndPrint(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X ", b));
}
System.out.println(sb.toString());
}
public static void main(String[] args) throws IOException, InterruptedException, NoSuchAlgorithmException {
JfragWS j = new JfragWS();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("Write something to the client!");
j.sendMessage(br.readLine().getBytes());
}
}
}