I am writing telnet client for cisco router using apache.commons.net.telnet. But i have problem. Here is code sample:
static TelnetClient telnetClient = new TelnetClient();
public static void main(String[] args) throws IOException {
setOptionHandlers();
telnetClient.connect("192.168.127.100");
read();
telnetClient.disconnect();
}
private static void setOptionHandlers() throws IOException {
ArrayList<TelnetOptionHandler> optionHandlers =
new ArrayList<TelnetOptionHandler>();
optionHandlers.add(new TerminalTypeOptionHandler("VT100", false, false, true, false));
optionHandlers.add(new EchoOptionHandler(true, false, true, false));
optionHandlers.add(new SuppressGAOptionHandler(true, true, true, true));
for (TelnetOptionHandler handler : optionHandlers) {
try {
telnetClient.addOptionHandler(handler);
}
catch (InvalidTelnetOptionException e) {
System.err.println("Error registering option handler "
+ handler.getClass().getSimpleName());
}
}
}
public static void write(byte[] data) throws IOException {
telnetClient.getOutputStream().write(data);
telnetClient.getOutputStream().flush();
}
public static void read() throws IOException {
System.out.println("Read");
byte[] buff = new byte[1024];
int read;
if((read = telnetClient.getInputStream().read(buff)) > 0) {
System.out.println(new String(buff, 0, read));
}
System.out.println("read="+read);
}
In some cases it works correctly and shows prompt for password entering. But is other cases it works incorrectly - hangs by reading from telnet input stream. Run conditions are the same. Why do I get this situation?
If anyone has tips for writing cisco telnet client, i'll be glad to hear them!
I can reproduce this problem every time.
The problem can be worked-around by changing your read buffer size to 1 byte.
This accounts for why the readUntil() function from Looking for Java Telnet emulator works, at it simply calls read() for 1 byte.
That said, does this indicate a bug in org.apache.commons.net.telnet.TelnetClient?
Edit: Rolled back to an earlier version of Commons Net and the problem disappeared !
Related
My spring websocket code runs in Liberty server. The code works fine in local. When I move to my server, when I try from 'Simple Websocket Client', I get an error like
WebSocket connection to 'wss://url' failed: One or more reserved bits
are on: reserved1 = 0, reserved2 = 1, reserved3 = 1
On the server side logs, I can see that afterConnectionEstablished method gets triggered, and immediately afterConnectionClosed gets triggered and when I print close status, it gives me
Code 1002 Reason:: Invalid reserved bit.
Am not clear on what this means and what are reasons this could come from.
public class NotificationHandler extends TextWebSocketHandler {
Logger logger = LogManager.getLogger(NotificationHandler.class);
#Override
public void afterConnectionEstablished(WebSocketSession session)
throws IOException {
logger.info("In NotificationHandler, afterConnectionEstablished.. ");
session.sendMessage(new TextMessage("Hello !"));
}
#Override
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
logger.info("In NotificationHandler, handleTextMessage.. ");
session.sendMessage(new TextMessage("Hello Text Message!"));
}
#Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
logger.info("In NotificationHandler, afterConnectionClosed, Code:: "+ status.getCode() + ".. Reason:: " + status.getReason());
}
}
Please let me know if you need more details.
Given the exact wording, that is not a reason code coming from the Liberty Websocket code, so I am guessing it is coming from the Spring code. If you are running on Liberty I would think you would want the system configured to use the Liberty Websocket code and not another provider.
Here is my code
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private String TAG = "app comm";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int code = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (code == ConnectionResult.SUCCESS) {
Log.d(TAG, "success ");
buildGoogleApiClient();
} else {
Log.d(TAG, "fail ");
}
}
private void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Nearby.CONNECTIONS_API).addConnectionCallbacks(this).addOnConnectionFailedListener(this).build();
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.d(TAG,"connected");
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG,"suspended");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d(TAG,"failed");
}
}
I am new to this
I run this program in raspberry pi 3
I have checked and internet is working.
isGoogleServicesAvailable is returning true.
but none of the override methods called. I don't know what I am missing.
Here is my log
Connected to process 8191 on device google-iot_rpi3-192.168.1.2:5555
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
I/zygote: Late-enabling -Xcheck:jni
W/zygote: Using default instruction set features for ARM CPU variant (generic) using conservative defaults
I/InstantRun: starting instant run server: is main process
V/first log: first raspberry log message
D/app comm: success
D/vndksupport: Loading /vendor/lib/hw/android.hardware.graphics.mapper#2.0-impl.so from current namespace instead of sphal namespace.
Looking at your code snippet, you are not calling the connect method after building it, which is what actually starts the connection and gives a callback.
I'm writing a local HTTP server based on Netty. When I make a stress test, I'm limited on 400 requests/second.
To optimize my server, I've written a simple server based on Netty, that just sends "Hello World" to the client, and I launched a stress test with Gatling 2, and with this server, I've got the same result (limited to 400 req/s).
I use Yourkit for profiling, there is no extra GC activity, and my open/closed sockets are limited to 480 sockets/s.
I work with a MacBook Pro, with 4 cores, 16 GB of RAM, and I use Netty 4.1.
I'm surprised to be limited at 400 req/s, because the result of other benchmark tests show >20 000 req/s, or more. I understand that there are hardware limits, but 400 req/s, for a sending "hello World" on a 4 cores + 16 GB of Ram is very low.
Thank you in advance for your help, I don't know where to begin to optimize my Netty code.
Are there any concrete guidelines of optimizing Netty?
Here the source code of my hello world server, followed by the handler of my connections:
public class TestServer {
private static final Logger logger = LogManager.getLogger("TestServer");
int nbSockets = 0 ;
EventLoopGroup pool = new NioEventLoopGroup() ;
private void init(int port) {
EventLoopGroup bossGroup = new NioEventLoopGroup(100) ;
try {
long t1 = System.currentTimeMillis() ;
ServerBootstrap b = new ServerBootstrap().group(bossGroup);
b.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("decoder", new HttpRequestDecoder(8192, 8192 * 2,
8192 * 2));
ch.pipeline().addLast("encoder", new HttpResponseEncoder());
ch.pipeline().addLast(new TestServerHandler(TestServer.this));
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.err.println("Error");
super.exceptionCaught(ctx,cause);
}
})
.option(ChannelOption.SO_BACKLOG, 100000)
.option(ChannelOption.SO_KEEPALIVE,false)
.option(ChannelOption.TCP_NODELAY,false)
.option(ChannelOption.SO_REUSEADDR,true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,10000)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);;
scheduler.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
System.err.println(nbSockets);
nbSockets = 0 ;
}
},1, 1,TimeUnit.SECONDS) ;
// Bind and start to accept incoming connections.
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
System.err.println("Coucou");
}
}
public static void main(String[] args) {
TestServer testServer = new TestServer() ;
testServer.init(8888);
}
}
and here is the source code of my handler:
public class TestServerHandler extends ChannelInboundHandlerAdapter {
private final TestServer testServer;
public TestServerHandler(TestServer testServer) {
this.testServer = testServer ;
}
#Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
process(ctx, msg);
} catch (Throwable e) {
e.printStackTrace();
}
}
public void process(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.channel().writeAndFlush(buildHttpResponse()).addListener(new GenericFutureListener<Future<? super Void>>() {
#Override
public void operationComplete(Future<? super Void> future) throws Exception {
ctx.channel().close() ;
testServer.nbSockets ++ ;
}
}) ;
}
public DefaultFullHttpResponse buildHttpResponse() {
String body = "hello world" ;
byte[] bytes = body.getBytes(Charset.forName("UTF-8"));
ByteBuf byteContent = Unpooled.copiedBuffer(bytes);
HttpResponseStatus httpResponseStatus =HttpResponseStatus.OK;
DefaultFullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
httpResponseStatus, byteContent);
return httpResponse;
}
}
You've disabled keep-alive and are closing the connection on every request, so I suspect you spend most of your time opening and closing HTTP connections.
because the result of other benchmark tests show >20 000 req/s, or more
Which other benchmarks are you referring to? There's a very good chance they were both pooling connections, and using HTTP pipelining, hence a very different usage from yours.
Back to your original question (how to optimize Netty), there's two kind of things you could do:
Micro-optimize allocations: using pooled ByteBuffers, or even better computing them only once
Switch to native epoll transport (Linux only)
But all those improvement won't probably amount to much compare to connection handling.
I'm trying to implement my own ftp-server without any libraries on Java. For testing my server I use FTP-client FileZilla. The problem is that I can't send list of files in the current directory through data connection (or in other words I can't implement FTP command LIST).
I've tried both active and passive modes.
Here is the output of FileZilla:
Command: PASV
Response: 227 Entering Passive Mode (192,168,0,87,125,63)
Command: LIST
Response: 150 Opening BINARY mode data connection.
// Here I'm trying to send list of files through data connection
Response: 226 Transfer complete.
Error: Connection timed out
Error: Failed to retrieve directory listing
Here is my implementation of LIST and PASV commands:
public class FTPCommandSocket implements Runnable {
Socket command_socket;
Socket data_socket = null;
FTPDataSocket ftpds = null;
ServerSocket ss = null;
// ...
#Override
public void run() {
try {
// Send response to the client.
sendResponse("220 WELCOME\n");
while(from_client_command.read(input_b) != -1)
{
String input = new String(input_b);
String cmd = parseInput(input);
switch(cmd) {
// ... (other commands)
case Command.PASV:
sendResponse("227 Entering Passive Mode (192,168,0,87,125,63)\n");
ss = new ServerSocket(125 * 256 + 63);
data_socket = ss.accept();
ftpds = new FTPDataSocket(data_socket);
break;
case Command.LIST:
sendResponse("150 Opening BINARY mode data connection.\n");
ftpds.sendFilesList(cur_path);
Thread.sleep(500);
sendResponse("226 Transfer complete.\n");
break;
//... (other commands)
default:
sendResponse("502 Command is not implemented.\n");
}
}
} catch (...) {}
}
private void sendResponse(String string) throws IOException {
to_client_command.write(string.getBytes());
to_client_command.flush();
}
}
This is data connection class:
public class FTPDataSocket {
Socket data_socket;
OutputStream to_client_data;
InputStream from_client_data;
private final byte[] input_b = new byte[15000];
public FTPDataSocket(Socket s) throws IOException {
this.data_socket = s;
from_client_data = data_socket.getInputStream();
to_client_data = data_socket.getOutputStream();
}
public void sendFilesList(String path) throws IOException {
// Debug version: there are no real files yet.
sendResponse("-rwxr-xr-x 1 100 100 14757 a.out\r\n");
}
private void sendResponse(String string) throws IOException {
to_client_data.write(string.getBytes());
to_client_data.flush();
System.out.print(string);
}
}
Do you have any ideas, what I'm doing wrong?
Thank you in advance!
The problem was that socket was not closed after sending data.
I had implemented ISO SERVER by using ASCII channel and ASCII packager and listening on a port and giving response to ISO requests.
how can i make my server that accepts concurrent requests and send the response.
Please
if you are using Q2, just deploy QServer and set the minSessions and maxSessions which its default value is 0 and 100.
here example jPOS server that handle concurent request:
http://didikhari.web.id/java/jpos-client-receive-response-specific-port/
ISOServer works with a threadpool, so you can accept concurrent requests out of the box. Every socket connection is handled by its own thread. So, I think all you have to do is assign a ISORequestListener to your ISOServer to actually process your incoming messages.
Here's a test program taken from the jPOS guide:
public class Test implements ISORequestListener {
public Test () {
super();
}
public boolean process (ISOSource source, ISOMsg m) {
try {
m.setResponseMTI ();
m.set (39, "00");
source.send (m);
} catch (ISOException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
public static void main (String[] args) throws Exception {
Logger logger = new Logger ();
logger.addListener (new SimpleLogListener (System.out));
ServerChannel channel = new XMLChannel (new XMLPackager());
((LogSource)channel).setLogger (logger, "channel");
ISOServer server = new ISOServer (8000, channel, null);
server.setLogger (logger, "server");
server.addISORequestListener (new Test ());
new Thread (server).start ();
}
}