I'm playing with this http server example and I have to questions:
1) instead of this static answer string "Hello world", I would like to change the string with the word of the URL. So if I type http://localhost:8004/example and reload the page it should show example.
2) How can I stop the server? Because it always says that the port is already bound if I try again.
Does someone has an idea?
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
/*
* a simple static http server
*/
public class SimpleHttpServer {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8004), 0);
server.createContext("/test", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
static class MyHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
String response = "Hello world";
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
You start the server, then the main method terminates, leaving the server in its background thread, continuing to occupy the port. You need to wait until some event, such as the main thread being interrupted, and stop the server. Also, you can obtain the path component of the request URI using t.getRequestURI().getPath().
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class SimpleHttpServer {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8004), 0);
server.createContext("/test", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
try
{
while(!Thread.currentThread().isInterrupted())
Thread.sleep(100);
}
catch(InterruptedException e)
{
}
finally
{
server.stop(0);
}
}
static class MyHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
String response = t.getRequestURI().getPath();
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
Related
I am writing some code to collect some controller's request param and response body.
Since the project framework is apache CXF, which version is 3.1.18,
I write an interceptor extends AbstractPhaseInterceptor to collect param in phase Phase.RECEIVE, which is working.
But when a write an outInterceptor extends AbstractPhaseInterceptor to collect the response of the controller, I find there no way for me to do this, there just one method handleMessage(Message message) in the interceptor, I can not fetch anything I want from the message
Can anybody help me? I am new to CXF. Thanks!
I found the answer from the other blob
package XXX.web.webservice.interceptor;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.log4j.Logger;
public class ArtifactOutInterceptor extends AbstractPhaseInterceptor<Message>{
private static final Logger log = Logger.getLogger(ArtifactOutInterceptor.class);
public ArtifactOutInterceptor() {
//这儿使用pre_stream,意思为在流关闭之前
super(Phase.PRE_STREAM);
}
public void handleMessage(Message message) {
try {
OutputStream os = message.getContent(OutputStream.class);
CachedStream cs = new CachedStream();
message.setContent(OutputStream.class, cs);
message.getInterceptorChain().doIntercept(message);
CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);
InputStream in = csnew.getInputStream();
String xml = IOUtils.toString(in);
//这里对xml做处理,处理完后同理,写回流中
IOUtils.copy(new ByteArrayInputStream(xml.getBytes()), os);
cs.close();
os.flush();
message.setContent(OutputStream.class, os);
} catch (Exception e) {
log.error("Error when split original inputStream. CausedBy : " + "\n" + e);
}
}
private class CachedStream extends CachedOutputStream {
public CachedStream() {
super();
}
protected void doFlush() throws IOException {
currentStream.flush();
}
protected void doClose() throws IOException {
}
protected void onWrite() throws IOException {
}
}
}
I was working on a simple application to transfer files between two machines using UDP, but that turned out to be lossy and unreliable, so while searching the Internet I found this project named Simple Reliable UDP here, but they don't have any documentation or any example code. So if there is any who can help me with this code I will be grateful because I'm newbie in Java. I started with writing simple server client app, but I got address already bind exception. To make clear I want to use UDP connections only that's why I'm trying to implement ReliableServerSocket and ReliableSocket.
package stackoverflow;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.rudp.ReliableServerSocket;
import net.rudp.ReliableSocket;
/**
*
* #author Nika
*/
public class udpServer implements Runnable{
ReliableServerSocket rss;
///ocket rs;
ReliableSocket rs;
public udpServer() throws IOException {
rss= new ReliableServerSocket(9876);
}
public void run(){
while (true){
try {
rs=(ReliableSocket)rss.accept();
System.out.println("Connection Accepted");
System.out.println(""+rs.getInetAddress());
BufferedReader inReader = new BufferedReader (new InputStreamReader (rs.getInputStream()));
//BufferedWriter outReader = new BufferedWriter (new OutputStreamWriter (rs.getOutputStream()));
String str= ""+inReader.readLine();
if(str.contains("UPLOAD")){
System.out.println("Client wants to upload file");
}else if(str.contains("D1")){
System.out.println("Client wants to download file");
}
} catch (IOException ex) {
Logger.getLogger(udpServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String args[]) throws Exception
{
System.out.println("UDP Server Executed");
Thread t= new Thread( new udpServer());
t.start();
}
}
Client Code here
package stackoverflow;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import net.rudp.ReliableSocket;
/**
*
* #author Nika
*/
public class UdpFileClient {
BufferedWriter outReader;
ReliableSocket server;
public UdpFileClient(boolean b1, boolean b2) throws IOException {
if (b1) {
server = new ReliableSocket("127.0.0.1", 9876);
outReader = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));
outReader.write("D1");
System.out.println("Download Req Sent From Client");
server.close();
outReader.flush();
outReader.close();
}
if (b2) {
server = new ReliableSocket("127.0.0.1", 9876);
outReader = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));
outReader.write("UPLOAD");
System.out.println("Upload Req Sent From Client");
server.close();
outReader.flush();
outReader.close();
}
}
public static void main(String args[]) throws Exception {
System.out.println("UDP CLient Executed");
new UdpFileClient(true, true);
}
}
I already know I can use TCP/IP, but it is kind of requirement for the project to use UDP. If any other way to send files in lossless way using UDP with good speed will also be helpful.
Thanks in advance!!
I tried RUDP and found that i was not printing my output, i know this is a silly mistake.
UDP Client
package UDPClient;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import net.rudp.ReliableSocket;
/**
*
* #author Nika
*/
public class UDPtestc {
ReliableSocket server;
public UDPtestc() throws IOException {
server = new ReliableSocket();
server.connect(new InetSocketAddress("127.0.0.1", 9876));
byte[] buffer = new byte[1024];
int count,progress=0;
InputStream in = server.getInputStream();
while((count=in.read(buffer)) >0){
progress+=count;
System.out.println(""+progress);
}
server.close();
}
public static void main(String[] args) throws IOException {
new UDPtestc();
}
}
UDPserver
package UDPServer;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.rudp.ReliableServerSocket;
import net.rudp.ReliableSocket;
/**
*
* #author Nika
*/
public class UDPtests implements Runnable {
ReliableServerSocket rss;
ReliableSocket rs;
String file;
FileInputStream bin;
public UDPtests() throws IOException {
rss = new ReliableServerSocket(9876);
Thread serverthread = new Thread(this);
serverthread.start();
}
public void run() {
while (true) {
try {
rs = (ReliableSocket)rss.accept();
System.out.println("Connection Accepted");
System.out.println("" + rs.getRemoteSocketAddress());
file = "";
Long size=0L;
file += "10MB.txt";
size+=10*1024*1024;
RandomAccessFile r1= new RandomAccessFile(file,"rw");
r1.setLength(size);
byte[] sendData = new byte[1024];
OutputStream os = rs.getOutputStream();
//FileOutputStream wr = new FileOutputStream(new File(file));
bin= new FileInputStream(file);
int bytesReceived = 0;
int progress = 0;
while ((bytesReceived = bin.read(sendData)) > 0) {
/* Write to the file */
os.write(sendData, 0, bytesReceived);
progress += bytesReceived;
System.out.println(""+progress);
}
} catch (IOException ex) {
Logger.getLogger(udpServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public static void main(String[] args) throws IOException {
new UDPtests();
}
}
Soon i will post other tuts on RUDP if it will be possible.
I've been trying to make some sort of alpha key system for my game. I thought in order to prevent people from decompiling my jar and changing around some code to bypass the system and get straight into my game, I thought about making it so after some verification, the server would send a serialized copy of a ClassLoader object to the client, which the client can then use to load the required files off an external host to start running the game.
Turns out it's not working at all.. ClassLoader seems to be non-serializeable. Are there any suggestions on how I could make a simliar system, or some way to somehow be able to ram that ClassLoader object through?
Source code:
Server.java:
package org.arno;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import org.arno.Packet.ClassLoaderPacket;
public class InitServer {
private static ObjectOutputStream out;
private static ObjectInputStream in;
private static ServerSocket server;
private static Socket connection;
private static final float HANDSHAKE_UID = 9678;
public static void main(String[] args) {
startServer();
}
private static void startServer() {
try {
server = new ServerSocket(7799,100);
System.out.println("[LoginServer] Initiated");
while (true) {
waitForClientConnection();
setStreams();
waitForHandShake();
sendData();
closeClientConnection();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void closeClientConnection() throws Exception {
out.close();
in.close();
connection.close();
}
private static void waitForHandShake() throws Exception{
float handshake = (float) in.readObject();
System.out.println(handshake == HANDSHAKE_UID? "Handshakes match UID" : "Wrong handshake sent");
}
private static void sendData() throws Exception {
ClassLoaderPacket.writeObject(new ClassLoaderPacket(out));
System.out.println("DATA SEND");
}
private static void waitForClientConnection() throws Exception {
connection = server.accept();
System.out.println("[LoginServer] Connection made from IP ["
+ connection.getInetAddress().getHostAddress() + "]");
}
private static void setStreams() throws Exception {
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
in = new ObjectInputStream(connection.getInputStream());
}
}
ClassLoaderPacket.java:
package org.arno.Packet;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
/**
* #author arno
* File: ClassLoaderPacket.java
*/
public class ClassLoaderPacket implements Serializable {
static ObjectOutputStream out;
private transient ClassLoader cL;
private static final String GAME_URL = "https://dl.dropboxusercontent.com/u/9385659/Avalonpk718.jar";
public ClassLoaderPacket(ObjectOutputStream out) throws MalformedURLException {
this.out = out;
cL = new URLClassLoader(new URL[] { new URL(GAME_URL) });
}
public ClassLoader getClassLoaderContext() {
return cL;
}
public static void writeObject(ClassLoaderPacket packet) throws IOException {
out.writeObject(packet.getClassLoaderContext());
}
}
Client sided reading:
public void receiveData() throws Exception {
gameLoader = (ClassLoader) in.readObject();
}
I think there are too much of complex fields in the ClassLoader in order to serialize it. Additionally, it should implement Serializable interface and have serialVersionUID in the serializable class.
Would it be enough just to obfuscate the code? I think there are plenty of tools which may help you to conceal your code.
Here is the useful thread about java code obfuscation/protection: Best Java obfuscator?
I've played a bit with netty and followed a video(https://www.youtube.com/watch?v=tsz-assb1X8) to build a chat server and client the server works properly(I tested with telnet and here it works) but the client does not recives data. The channelRead method in ChatClinetHandler.java were never called but the channelReadComplete were called.
ChatClient.java
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ChatClient {
public static void main(String args[]) {
try {
new ChatClient(new InetSocketAddress("localhost", 8000)).run();
} catch (Exception ex) {
Logger.getLogger(ChatClient.class.getName()).log(Level.SEVERE, null, ex);
}
}
private final InetSocketAddress server;
public ChatClient(InetSocketAddress server) {
this.server = server;
}
public void run() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChatClientInitializer());
Channel channel = bootstrap.connect(server).sync().channel();
System.out.println("Connected to Server: " + server.toString());
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (channel.isActive()) {
String userMessage = in.readLine();
channel.writeAndFlush(userMessage + "\r\n");
if (userMessage.equalsIgnoreCase("bye")) {
group.shutdownGracefully();
break;
}
}
} finally {
group.shutdownGracefully();
}
}
}
ChatClientInitializer.java
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder;
public class ChatClientInitializer extends ChannelInitializer<SocketChannel> {
#Override
protected void initChannel(SocketChannel c) throws Exception {
ChannelPipeline pipeline = c.pipeline();
pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
pipeline.addLast(new StringDecoder());
pipeline.addLast(new StringEncoder());
pipeline.addLast(new ChatClientHandler());
} }
ChatClinetHandler.java
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class ChatClientHandler extends ChannelInboundHandlerAdapter {
#Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(msg.toString());
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx,
Throwable cause) {
cause.printStackTrace();
}
}
Sorry my mistake i forgot to send "\r\n" with each message.
Although shim_ claims to have determined that the problem is not sending "\r\n" with each message, I see the need to provide a clarification here.
In ChatClientInitializer.java you see a handler named framer which is a DelimiterBasedFrameDecoder object with a line delimiter in that specific example (More info on DelimiterBasedFrameDecoder can be found here).
So, that means the client is expecting messages that ends with "\r\n" on that specific channel. If a message not ending with "\r\n" is received, then the channelRead() method will not be provoked.
So we're fooling around with ServerSockets in class, making a very simple HTTP server that takes a request, does nothing with it, and responds with a 200 OK followed by some HTML content.
I've been trying to figure out this problem for two days, and I haven't been able to get to grips with it, and neither has my teacher. I've come to think it is a problem with closing the server, for some odd reason. I've fixed the problem, but would just like to know why I happened in the first place.
Here are three snippets:
HttpServer.class:
package httpserver;
import java.io.Closeable;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class HttpServer implements Closeable {
public static final int PORT = 80;
public static final int BACKLOG = 1;
public static final String ROOT_CATALOG = "C:/HttpServer/";
private ServerSocket server;
private Socket client;
private Scanner in;
private PrintWriter out;
private String request;
public HttpServer() throws IOException {
server = new ServerSocket(PORT, BACKLOG);
}
public Socket accept() throws IOException {
client = server.accept();
in = new Scanner(client.getInputStream());
out = new PrintWriter(client.getOutputStream());
return client;
}
public void recieve() {
request = in.nextLine();
System.out.println(request);
}
public void respond(final String message) {
out.print(message);
out.flush();
}
#Override
public void close() throws IOException {
if(!server.isClosed()) {
client = null;
server = null;
}
}
}
Main.class solution that works:
package httpserver;
import java.io.IOException;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws IOException {
HttpServer server = new HttpServer();
Socket client;
while(true) {
client = server.accept();
server.recieve();
server.respond("HTTP/1.0 200 OK\r\n"
+ "Content-Type: text/html\r\n"
+ "\r\n"
+ "<html><body><b>hello..</b></body></html>");
client.close();
}
}
}
Main.class solution that doesn't work:
package httpserver;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try(HttpServer server = new HttpServer()) {
while (true) {
server.accept();
server.recieve();
server.respond("HTTP/1.0 200 OK\r\n"
+ "Content-Type: text/html\r\n"
+ "\r\n"
+ "<html><body><b>hello..</b></body></html>");
}
} catch(IOException ex) {
System.out.println("We have a problem: " + ex.getMessage());
}
}
}
I could imagine it has something to do with not closing the client socket after each loop iteration. But even so, it should at least go through once, before bugging up in that case. I really can't see what the problem is supposed to be.
No error messages, nothing...
You do not specify any Content-length when sending the HTTP, so the browser does not know when to stop reading for more data. See How to know when HTTP-server is done sending data for more info.
In the working example you closed the client socket, which tells the browser there is no more data - for your ambitions this might be enough if you don't want the browser to respond.