I would like help creating a relay bot with PircBot. I want it for each message it sends a message to a channel with that message. And I wish to have this multi networks. I made a command
if (split[0].equalsIgnoreCase(commandPrefix + "addnet")) {
// sendRawLine("QUIT : joining " + split[1]);
BrookieBot bot = new BrookieBot();
bot.setVerbose(true);
addnet = addnet + " " + split[1];
try {
bot.connect(split[1]);
sendMessage("nickserv", "identify pass");
bot.joinChannel("#brookies-use-of-bot");
} catch (NickAlreadyInUseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IrcException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bot = new BrookieBot();
quit = 6;
this.joinChannel("#brookies-use-of-bot");
}
That is how I made it connect to multiple networks, but I want it to reconise the net and send a message each time it recieves a message to that channel no matter what network.
Having the message be in this format: [<net>] [<sender>] [<message>]. Thank you for all your help! I have this version: http://www.jibble.org/pircbot.php
I've made one such relay bot before. Let's discuss what you need.
When a bot recieves a message in a channel to be relayed, the message is sent using an array of bots to their respective channels based on server and channel combination, provided:
The channel selected in the loop is not the current channel
The channel is in the list of to be synchronized channels
The sender is not part of the bot names to prevent infinite loops
The same goes for quit, part, join and anything else you want.
1) PircBot isn't good for multi networks. Also, it has several design problems.
I would recommend PircBotX.
2) If you really have to use PircBot:
Create one PircBot object per connection.
That will create one thread per PircBot.
Then, create a bus which will distribute the messages amongst PircBot instances.
Be careful with synchronization.
For an example on how to send messages outside PircBot object, see JawaBot, which is based on it.
Related
I have my below code which can captures packets from the interface using pcap4j but I am not sure how can I print the request and the response data present in the packet. For example, if I make a REST call from a postman then I want to trace the request and response. This is the same as Wireshark. I am stuck in the last part where I am able to capture the packet but not sure how do I read the packet contents which I can print on console.
try {
InetAddress addr = InetAddress.getByName("10.227.178.25");
PcapNetworkInterface device = Pcaps.getDevByAddress(addr);
System.out.println("You chose: " + device);
int snapshotLength = 64 * 1024; // in bytes
int readTimeout = 50; // in milliseconds
final PcapHandle handle;
handle = device.openLive(snapshotLength, PromiscuousMode.PROMISCUOUS, readTimeout);
String filter = "tcp port 80";
handle.setFilter(filter, BpfCompileMode.OPTIMIZE);
// Create a listener that defines what to do with the received packets
PacketListener listener = new PacketListener() {
#Override
public void gotPacket(Packet packet) {
// Override the default gotPacket() function and process packet
System.out.println(handle.getTimestamp());
System.out.println(packet);
byte[] b = packet.getRawData();
Packet p = packet.getPayload();
}
};
// Tell the handle to loop using the listener we created
try {
int maxPackets = 50;
handle.loop(maxPackets, listener);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Cleanup when complete
handle.close();
}catch(Exception e) {
e.printStackTrace();
}
So I have two questions :
How can I capture the HTTP request and response and print it on the console.
How can I let the java code run continuously such that it keeps on capturing the packets.
I did check the pcap4j documents but not sure how I can read the packet contents where I can read the HTTP request and HTTP response.
For the first question:
If you set [maxPackets] to -1, it will run continuously.
You can see many such implementations from the official Sample.
As for the second question:
Currently, the official library does not support Http Packet. You need to implement it manually by yourself.
You can check https://github.com/kaitoy/pcap4j/issues/85.
I've created a client-server connection, something like a chat system. Previously I was using a while loop on the client side, and it was waiting to read a message from the console every time (of course server has a while loop as well to serve forever). But now, I'm trying to first create a connection at the beginning of the session, and then occasionally send a message during the session, so to maintain a permanent and persistent connection.
Currently, without the while loop, the client closes the connection and I don't know how to find a workaround.
Here is the client code:
import java.net.*;
import java.io.*;
public class ControlClientTest {
private Socket socket = null;
// private BufferedReader console = null;
private DataOutputStream streamOut = null;
public static void main(String args[]) throws InterruptedException {
ControlClientTest client = null;
String IP="127.0.0.1";
client = new ControlClientTest(IP, 5555);
}
public ControlClientTest(String serverName, int serverPort) throws InterruptedException {
System.out.println("Establishing connection. Please wait ...");
try {
socket = new Socket(serverName, serverPort);
System.out.println("Connected: " + socket);
start();
} catch (UnknownHostException uhe) {
System.out.println("Host unknown: " + uhe.getMessage());
} catch (IOException ioe) {
System.out.println("Unexpected exception: " + ioe.getMessage());
}
String line = "";
// while (!line.equals(".bye")) {
try {
Thread.sleep(1000);
//TODO get data from input
// line = console.readLine();
line="1";
if(line.equals("1"))
line="1,123";
streamOut.writeUTF(line);
streamOut.flush();
} catch (IOException ioe) {
System.out.println("Sending error: " + ioe.getMessage());
}
// }
}
public void start() throws IOException {
// console = new BufferedReader(new InputStreamReader(System.in));
streamOut = new DataOutputStream(socket.getOutputStream());
}
}
And here is the Server code:
import java.awt.*;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ControlServer {
private Socket socket = null;
private ServerSocket server = null;
private DataInputStream streamIn = null;
public static void main(String args[]) {
ControlServer server = null;
server = new ControlServer(5555);
}
public ControlServer(int port) {
try {
System.out
.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted: " + socket);
open();
boolean done = false;
while (!done) {
try {
String line = streamIn.readUTF();
// TODO get the data and do something
System.out.println(line);
done = line.equals(".bye");
} catch (IOException ioe) {
done = true;
}
}
close();
} catch (IOException ioe) {
System.out.println(ioe);
}
}
public void open() throws IOException {
streamIn = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
}
public void close() throws IOException {
if (socket != null)
socket.close();
if (streamIn != null)
streamIn.close();
}
}
I would like to summarize some good practices regarding the stability of TCP/IP connections which I apply on a daily basis.
Good practice 1 : Built-in Keep-Alive
socket.setKeepAlive(true);
It automatically sends a signal after a period of inactivity and checks for a reply. The keep-alive interval is operating system dependent though, and has some shortcomings. But all by all, it could improve the stability of your connection.
Good practice 2 : SoTimeout
Whenver you perform a read (or readUTF in your case), your thread will actually block forever. In my experience this is bad practice for the following reasons: It's difficult to close your application. Just calling socket.close() is dirty.
A clean solution, is a simple read time-out (e.g. 200ms). You can do this with the setSoTimeoutmethod. When the read() method timeouts it will throw a SocketTimeoutException. (which is a subclass of IOException).
socket.setSoTimeout(timeoutInterval);
Here is an example to implement the loop. Please note the shutdown condition. Just set it to true, and your thread will die peacefully.
while (!shutdown)
{
try
{
// some method that calls your read and parses the message.
code = readData();
if (code == null) continue;
}
catch (SocketTimeoutException ste)
{
// A SocketTimeoutExc. is a simple read timeout, just ignore it.
// other IOExceptions will not be stopped here.
}
}
Good practice 3 : Tcp No-Delay
Use the following setting when you are often interfacing small commands that need to be handled quickly.
try
{
socket.setTcpNoDelay(true);
}
catch (SocketException e)
{
}
Good practice 4 : A heartbeat
Actually there are a lot of side scenario's that are not covered yet.
One of them for example are server applications that are designed to only communicate with 1 client at a time. Sometimes they accept connections and even accept messages, but never reply to them.
Another one: sometimes when you lose your connection it actually can take a long time before your OS notices this. Possibly due to the shortcomings described in good practice 3, but also in more complex network situations (e.g. using RS232-To-Ethernet converters, VMware servers, etc) this happens often.
The solution here is to create a thread that sends a message every x seconds and then waits for a reply. (e.g. every 15 seconds). For this you need to create a second thread that just sends a message every 15 seconds. Secondly, you need to expand the code of good practice 2 a little bit.
try
{
code = readData();
if (code == null) continue;
lastRead = System.currentTimeMillis();
// whenever you receive the heart beat reply, just ignore it.
if (MSG_HEARTBEAT.equals(code)) continue;
// todo: handle other messages
}
catch (SocketTimeoutException ste)
{
// in a typical situation the soTimeout is about 200ms
// the heartbeat interval is usually a couple of seconds.
// and the heartbeat timeout interval a couple of seconds more.
if ((heartbeatTimeoutInterval > 0) &&
((System.currentTimeMillis() - lastRead) > heartbeatTimeoutInterval))
{
// no reply to heartbeat received.
// end the loop and perform a reconnect.
break;
}
}
You need to decide if your client or server should send the message. That decision is not so important. But e.g. if your client sends the message, then your client will need an additional thread to send the message. Your server should send a reply when it receives the message. When your client receives the answer, it should just continue (i.e. see code above). And both parties should check: "how long has it been?" in a very similar way.
You could wrap a thread around the connection and have it periodically send a status to keep the line open, say every 30 seconds or whatever. Then, when it actually has data to send it would reset the keep alive to be 30 seconds after the last transmission. The status could be helpful to see if the client is still alive anyway, so at least it can be a useful ping.
Also, you should change your server code, you appear to only handle one connection at the moment. You should loop and when a socket connection comes in spawn a thread to handle the client request and go back to listening. I may be reading to much into what may just be your test code, though.
Make the client socket connection wrapped around a thread. Use a blocking queue to wait for messages. There should only be a single sender queue throughout your application, so use a singleton pattern.
e.g.
QueueSingleton queue = QueueSingleton.getSenderQueue();
Message message = queue.take() // blocks thread
send(message); //send message to server
When you need to send a message to the server, you can use the blocking queue to send the message.
QueueSingleton queue = QueueSingleton.getSenderQueue();
queue.put(message)
The client thread will wake up and process the message.
For maintaining the connection, use a timer task. This is special type of thread that calls a run method repetitively at specified periods. You can use this to post a message, a ping message, every so often.
For processing the received message, you could have another thread, waiting for messages on another blocking queue (receiver queue). The client thread will put the received message on this queue.
I want to check whether server is still connected to the client or not before reading from stream. How to do that in java? My current code is as below.Will this check only for client socket?
public void receiveResultFromServer() {
try {
while(!clientSocket.isClosed()) {
try{
Object obj = inStream.readObject();
if (obj instanceof Command) {
ConnectionManager.parseCommand((Command) obj);
} else if (obj instanceof CommandExecResult) {
ConnectionManager.parseCommandExecutionResult((CommandExecResult) obj);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
} catch(Exception e) {
e.printStackTrace();
}
Knowing connectivity just before reading streams is not good. Instead design a heartbeat mechanism.
Algorithm :
a) design two commands using enum "SEND_BEAT" and "RECEIVE_BEAT" on both client and server.
b) Now as soon as your server starts, start a thread that sends a signal from server to client(HandShake Protocol) using the the commands and client will respond back to the signal to the server.
c) this sending signal job can be scheduled at regular interval of time, using Java Timer and TimerTask classes available for e.g.
scheduleAtFixedRate(new RunTimer(), 5000, 1000);
d) on the basis of response, maintain the status of client on the server.
e) Now you can use status for checking the connectivity between the client and server.
f) In fact, you can even design a re-connect mechanism which will try for certain number of times before final update.
h) Also you need to maintain the state as checkpoint as per your need.
hopefully above algo fulfills your demand.
If the peer has disconnected, your code will throw am EOFException. If there has been a network failure it might block forever, so you might want to consider using a read timeout, which would throw a SocketTimeoutException.
I am testing a chat application for number of users. So what I am trying is as follows:
I am trying to run my chat application by login for chat for only one user for 1000 times in for loop. here is my part of code .
public void LoginChatConnect() {
try {
// while(true){
for(int i=0;i<1000;i++){
System.out.println("inside loginChatLogin");
String userId = "Rahul";
String password = "rahul";
sockChatListen = new Socket("localhost", 5004);
// /sockChatListen.
dosChatListen = new DataOutputStream(
sockChatListen.getOutputStream());
disChatListen = new DataInputStream(sockChatListen.getInputStream());
dosChatListen.writeUTF(userId);
dosChatListen.writeUTF(password);
// System.out.println(dosChatListen.toString());
dosChatListen.flush();
// sockChatListen.close();
boolean b = sockChatListen.isClosed();
System.out.println("connection open**********************" + b);
sockChatListen.close();
System.out.println("connection closed**********************" + b);
count++;
System.out.println("count" + count);
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In above code I am just trying to login for only one user for 1000 times. But after certain login it is giving me this socket error.
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
Here I am trying to create a connection with a single port 5004. why I am getting error after 100+ successful connections(login).?
How should I recover this problem?
Any suggestions will be helpful.
What I understand from your post is that you want to simulate 1000 users logging to the chat server concurrently. I believe you are trying to test the load on your chat server.
However, from your code, I see that you are establishing and closing the socket connection every time in the loop. This is similar to 1000 users waiting in a queue and attempting to login to the server one after the other. This does not simulate the concurrent load but a 1000 sequential calls to the server and would not be appropriate to load test your server.
My comments are based on the above stated understanding. Please calrify if this is not the case.
Regarding the exception you get, I have no idea why it should not work after 100+ attempts. May be you need to check your server side code to figure out the problem.
Ok my issue is simple. I am trying to make simple chat but i feel that detection of disconnected client from server is mandatory. Chat works fine (without such detection) when i use simple:
if (this.in.ready()) //preinitialized buffered reader
this.dataIn=this.in.readLine();
I have browsed lots of websites/questions posted here and i read that ready() should be ommited since it blocks everything, that may be true since when i delete this ready() my chat no longer works, however it enables client disconnected detection.
In order to reach my goal i need to test if BufferedReader recieves null through readLine() but this does not work as it should either.
if (this.in.readLine()!=null){ //1. check if client disconnected
if (this.in.ready()) //2/
this.dataIn=this.in.readLine(); //3.
}
else
this.notice="Client disconnected!";
Now what happens when i apply code presented above. Initial if (1) is blocking the inner ready() (line 2) which is required to read actual message send over socket (3).
The other "order" does not work:
if (this.in.ready()){
this.dataIn=this.in.readLine();
}
else if (this.in.readLine()!=null)
this.notice="Client disconnected!";
This one also does not allow to send messages through socket.
*Yes, sending/recieving is realized in separate thread
*BufferedReader is initialized only once
Thread source code (if any1 would need it in order to take a look):
#Override
public void run() {
try {
if (this.isServer){
this.initServer();
this.initProcessData(sSocket);
}
else if (!this.isServer){
this.initClient();
this.initProcessData(clientSocket);
}
this.initDone=true;
} catch (IOException ex) {
Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
}
while(this.initDone){
try {
Thread.sleep(100);
if ((!this.dataOut.isEmpty())&&(this.dataOut!="")){
this.out.println(this.dataOut);
this.out.flush();
this.dataOut = "";
}
if (this.in.ready())
this.dataIn=this.in.readLine();
}
catch (IOException ex) {
Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
}
catch (InterruptedException ex) {
this.initDone=false;
Logger.getLogger(NetClass.class.getName()).log(Level.SEVERE, null, ex);
}
//System.out.println(this.notice);
}
}
The worst thing is that i have either proper detection of client disconnected or i have working chat.
Can anyone enlight me what should i do in order to combine those two together? Any help greatly appreciated.
Consider using java.io.ObjectInputStream and java.io.ObjectOutputStream. Use the blocking read() method in a separate worker thread, and loop until it returns -1 or throws an exception. Send String objects back and forth. In that way, you can also send messages with line feeds.