I´m trying to do a client that reads data from two servers simultaneously, for example, the client sends a string to both servers that capitalize it and then sends it back to the client.
Client Side
public class Client {
public static void main(String[] args) {
Connection c1 = new Connection("localhost", 2345, "example one");
c1.start();
Connection c2 = new Connection("localhost", 2346, "example two");
c2.start();
Server side
public class Connection implements Runnable {
private String host;
private int port;
private PrintWriter os;
private volatile boolean running = false;
private String stringToCap;
public Connection(String host, int port, String stringToCap) {
this.host = host;
this.port = port;
this.stringToCap = stringToCap;
}
public void start() {
try {
this.os = new PrintWriter(new Socket(host, port).getOutputStream());
} catch (IOException e) {
return;
}
running = true;
new Thread(this).start();
#Override
public void run() {
while(running) {
stringToCap.toUpperCase();
os.print(stringToCap);
}}
But I cant seem to get the server to print back the now capitalized string to the client. When I try the above I get nothing, Do I need a main method on the server side too?
Seems like you have a misconception.
Your current code is just a multi-thread application with 2 threads called Connection and not a true Client and Server application.
Please refer to the Java Tutorial, Custom Networking section.
Related
I have written a basic Netty Client that sends and receives data from a server. But I have started two instances of the Client on ports 8080 and 8081. Now how can I send a particular string on port 8080 and another string on 8081. I am confused in how to send the data on a particular port. I can able to send all the strings to the server. But I want to specify which string to be sent on which port to which server. Like I want to send "Hello server1" to server1 on port 8080 and "Hello server2" to server2 on port 8081.
How can I do that?
My Netty Client:
public class Client implements Runnable {
public int port;
private Channel channel;
public ChannelFuture channelFuture = null;
private String message;
int rcvBuf, sndBuf, lowWaterMark, highWaterMark;
public Client(int port) {
this.port = port;
rcvBuf = Integer.MAX_VALUE;
sndBuf = Integer.MAX_VALUE;
lowWaterMark = 2048;
highWaterMark = 3048;
}
#Override
public void run() {
try {
connectLoop();
} catch (Exception ex) {
System.err.println("Exception raised in Client class" + ex);
}
}
public final void connectLoop() throws InterruptedException {
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
Bootstrap bs = new Bootstrap();
bs.group(workGroup);
bs.channel(NioSocketChannel.class);
bs.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.SO_RCVBUF, rcvBuf)
.option(ChannelOption.SO_SNDBUF, sndBuf)
.option(ChannelOption.SO_LINGER, 0)
.option(ChannelOption.SO_KEEPALIVE, true)
.option(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(lowWaterMark, highWaterMark))
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
#Override
protected void initChannel(SocketChannel socketChannel) {
socketChannel.pipeline()
.addLast("patternDecoder", new ClientDecoder())
.addLast("Response Handler", new ClientHandler())// for receiving from Server
.addLast("exception Handler", new ClientExceptionHandler(port));
}
});
channelFuture = bs.connect("127.0.0.1", port).sync();
this.channel = channelFuture.channel();
if (channelFuture.isSuccess()) {
sendMessage("Hello server");
}
} catch (Exception ex) {
workGroup.shutdownGracefully();
System.err.println("ERROR : Server Not In Connection");
System.err.println("Connecting to Server...");
reconnect();
}
}
public void reconnect() throws InterruptedException {
Thread.sleep(10000);
connectLoop();
}
public void sendMessage(String data){
if (data != null)
{
channelFuture.channel().writeAndFlush(Unpooled.copiedBuffer(data.getBytes()));
System.out.println("Outgoing To Server >> " + data);
}
}
public static void main(String[] args){
Thread t = new Thread(new Client(8080));
t.start();
Thread t1 = new Thread(new Client(8081));
t1.start();
}
}
Client Handler
public class ClientHandler extends SimpleChannelInboundHandler<String> {
#Override
protected void channelRead0(ChannelHandlerContext ctx, final String message) throws Exception {
System.out.println("Incoming From Server >> " + message);
ctx.channel().writeAndFlush(Unpooled.wrappedBuffer("HELLO".getBytes()));
}
}
ClientExceptionHandler
public class ClientExceptionHandler extends ChannelInboundHandlerAdapter {
private int port;
public ClientExceptionHandler(int port){
this.port = port;
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.deregister();
ctx.disconnect();
ctx.close();
System.err.println("ERROR : Server Disconnected");
System.err.println("Reconnecting to Server...");
}
}
First you need to understand how ports work. Only servers will listen on specific ports. In your example server will listen from port 8080. Then multiple clients can connect to port 8080. Since you haven't given specific details, I suggest you to try one of the following.
Run two servers, one listens for port 8080 and other listens for port 8081. Then use two clients as you suggested.
Run only one server on port 8080 and connect two similar clients If you want to differentiate between clients use some kind of a message (e.g. send client id to server)
I'm relatively new to Java and I'm writing an application to interrogate an Apache HTTP server's access_log file; with this, I want to submit the IP Addresses individually (probably via the Apache HTTPClient library) to another Java instance on another server (as the Web server does not have FTP enabled) to pull some log files. At the moment I've managed to bumble my way through modifying a 'tail -f' equivalent class to suit the programs needs and then manipulate that data to get the IP Addresses that I need to do something with - I even managed to make the 'tail' class threaded so it could address multiple periods of time!
With that said, I want to use a for loop to iterate through each entry in my computerRebootList String Array and with each address create a thread to perform some more work but all I can think of is this;
for (String tmpIpAddress : computerRebootList ) {
ComputerIpHandler handler = new ComputerIpHandler();
}
and then create another class named ComputerIpHandler like so;
public class KioskIpHandler implements Runnable {
static final Logger logger = LogManager.getLogger( ComputerIpHandler.class );
#Override public void run() {
//do some code
}
public static void main(String computerIp) {
Thread mainThread = new Thread(new ComputerIpHandler());
mainThread.start();
try {
logger.info("log some stuff");
mainThread.join();
logger.info("yay it's done");
}
catch (InterruptedException errInterrupted) {
logger.error(errInterrupted.getMessage());
logger.error(errInterrupted.getStackTrace());
}
}
}
I read somewhere about ensuring that I need to manage resource limitations so I would have to create a maximum number of threads - arguably I could send something like 10 IPs to this class and then have the rest of the addresses 'queue' until the one has returned... I'm just not confident or fluent enough to be able to conceptualise these ideas.
EDIT: I omitted that I am restricted to Java 1.6 as this is the maximum compatible version of the JRE that we can use on this server - not sure if that hinders this effort somewhat...
Can anyone point me in the right direction?
Check ScheduledThreadPoolExecutor and ScheduledExecutorService classes in package java.util.concurrent in java API. Those and some other classes in that package would manage all resources for you. They are available in java since version 1.5
I recommend using Java's built in FTP connection platform to make a thread for continually receiving data on a specified port, until it receives a termination key.
Basically, one class will create a ServerSocket (open socket on server) and upon connection with another socket (the client socket) it would create a new thread for receiving information.
public class Server {
public ServerSocket ss;
public Socket clientSocket;
public Thread receiveingThread;
public BufferedReader inFromClient = null;
public boolean running = false;
public Server(int port) {
try {
ss = new ServerSocket(port);
startReceiving();
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void startReceiving() {
receiveingThread = new Thread("Recieve") {
public void run() {
String dataFromClient = new String("");
while (running) {
try {
inFromClient = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
dataFromClient = inFromClient.readLine();
} catch (Exception e) {
e.printStackTrace();
}
if (dataFromClient.equals("TERMINATOR_KEY") {
stopRecieving();
}
else if(!dataFromClient.equals("")) {
//add item to array
}
}
}
};
receiveingThread.start();
}
public synchronized void stopReceiving() {
try {
running = false;
receivingThread.join();
ss.close();
clientSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0);
}
public static void main(String[] args) {
new Server(yourPortHere);
}
}
then the client class would look something like:
public class Client {
public Socket socket;
public Thread send;
public Client(string serverPublicIP, int port) {
try {
socket = new Socket(serverPublicIP, port);
send("some IP address");
} catch (Exception e) {
e.printStackTrace();
}
}
public void send(String toSend) {
send = new Thread("Send") {
public void run() {
PrintWriter outToServer;
try {
outToServer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
outToServer.print(toSend);
outToServer.flush();
} catch (Exception e) {
e.printStackTrace();
}
finally {
outToServer.close();
}
}
};
send.start();
}
public static void main(String[] args) {
new Client("127.0.0.1", yourPortHere);
}
}
This is the link for the start of socket tutorials on the oracle site.
This is the Oracle Documentation for java.net.ServerSocket
This is the Oracle Documentation for java.net.Socket
I'm currently developing a TicTacToe multithreaded networked game for my university and I'm stuck on an annoying problem.
I wish that my server accepts 2 connections each time and then waits for other 2 connections etc.
The problem is that, in my code, if a client connects to the server and closes the connection while the second client is not yet connected to the server, the second client is not able to play because it "thinks" that the first client is connected and ready.
I thought to do something like this but I can't find a way to actually implement it.
The server is structured in 3 classes:
TTT_Server (which cointains the main method and launches threads);
TTT_ServerThread (which contains the thread(s) behaviour);
TTT (which contains the TicTacToe board and some method).
TTT_Server class:
public class TTT_Server()
{
private static ServerSocket serverSocket;
private static boolean running = true;
public static void main(String[] args)
{
try
{
// creazione ServerSocket sulla porta 8089
serverSocket = new ServerSocket(8089);
System.out.println("Server Socket creata e in ascolto sulla porta 8089");
while(running)
{
TTT ttt = new TTT();
Socket socket1 = serverSocket.accept();
Socket socket2 = serverSocket.accept();
TTT_ServerThread st1 = new TTT_ServerThread(socket1, 1, ttt, socket2);
TTT_ServerThread st2 = new TTT_ServerThread(socket2, 2, ttt, socket1);
st1.start();
st2.start();
System.out.println("thread lanciati");
}
}
catch(IOException e)
{
System.out.println(e);
running = false;
}
finally
{
try
{
serverSocket.close();
}
catch (IOException e)
{
System.out.println(e);
}
}
}
}
(a part of) TTT_ServerThread class:
private Socket socket;
private Socket socketOtherPlayer;
private BufferedReader in;
private PrintWriter out;
private PrintWriter outOtherPlayer;
private TTT TicTacToe;
private int player;
private boolean fineGioco;
private int counter = 0;
public TTT_ServerThread(Socket socket, int num_connessione, TTT ttt, Socket socketOtherPlayer)
{
this.socket = socket;
this.socketOtherPlayer = socketOtherPlayer;
this.player = num_connessione;
this.TicTacToe = ttt;
try
{
this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.out = new PrintWriter(socket.getOutputStream());
this.outOtherPlayer= new PrintWriter(socketOtherPlayer.getOutputStream());
}
catch(IOException e)
{
System.out.println(e);
}
}
#Override
public void run()
{
//[...]
}
(a part of) TTT class:
public class TTT
{
private int[] board = new int[9];
private int turno = 1;
public TTT()
{
for (int i = 0; i < 9; i++)
board[i] = 0;
}
protected synchronized void setBoard(int locazioneMossa, int giocatore)
{
board[locazioneMossa] = giocatore;
}
protected synchronized int getBoard(int locazioneMossa)
{
return board[locazioneMossa];
}
protected synchronized void setTurno(int turnoRicevuto)
{
turno = turnoRicevuto;
}
protected synchronized int getTurno()
{
return turno;
}
//[...]
}
Is there a way to implement a sort of that diagram that i thought?
Thank you all in advance for the help! And sorry for my English, it's not my primary language.
Instead of trying to "accept two connections at a time", you should accept one connection at a time. If there's no waiting connection, the connection should be put to a waiting list. If there is a waiting connection, pair them up.
That way you'll have a single accept() per loop, but 2 possible ways to handle them.
As the title suggests, I'm implementing a small project which allows clients to connect to server using multi-Threading to manage the connections. I would like to limit the connections and when the Server is full of requests, the other clients should be put in a queue, ex: the server only allows 2 clients to connect the server at the same time, the other clients until their turn.
This is my Server class
public class Server {
static BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
//Declare an instance of CommandParameter class
static CommandParameter par;
//Initialize a BufferedReader and BufferedWriter
static BufferedReader bufferedReader;
static BufferedWriter bufferWriter;
//
static int port;
static String serverData;
static int proc_count;
private static String command;
public static void main(String[] args) throws Exception {
command = userInput.readLine();
System.out.println("Server is available");
//Thread.sleep(2000);
processCommand(command);
startServer(port);
}
public static void startServer(int port) {
ServerSocket serverSocket = null;
try {
//create a port for server in order to listen incoming connections
serverSocket = new ServerSocket(port);
//allow client connect to server
} catch (IOException e) {
System.out.println(e);
}
while (true) {
try {
new ThreadSocket(serverSocket.accept(),serverData).start();
} catch (IOException ex) {
System.out.println("Server starts fail");
}
}
}
public static void processCommand(String input) {
//assign the user input to an String array
String inputLine = input;
int commandCount = checkCommand(inputLine);
if(commandCount>3 || commandCount ==-1){
System.out.println("Invalid command");
System.exit(1);
}
//assign the user input to an String array
String[] command = inputLine.split(" ");
par = new CommandParameter();
//JCommander parses the command to get the pairs parameter name and value
JCommander jc = new JCommander(par, command);
port = par.getPort();
serverData = par.getServerdata();
proc_count = par.getProc_count();
}
public static int checkCommand(String inputLine) {
int count = 0;
if (inputLine.contains("-port")) {
count++;
}else if (inputLine.contains("-data")) {
count++;
} else if (inputLine.contains("-proc_count")) {
count++;
} else{
return -1;
}
return count;
}
}
any ideas?
This is exactly where asynchronous IO becomes most useful. [large number of IO requests need to be handled by limited number of worker threads]. There are system calls in most of the modern operating systems allowing asynchronous IO operations. example, epoll in linux, IOCP in Windows, AIX and Solaris, KQueue in BSD flavors and Mac OS. In java, native non blocking calls are abstracted behind different SPIs - examples - sun.nio.ch.WindowsSelectorImpl, sun.nio.ch.KQueueSelectorImpl , sun.nio.ch.EPollSelectorImpl etc.
What I recommend you to use is Netty.
An example of servicing a large number of HTTP requests with using a smaller fixed number of threads is a simple task using netty API.
Sample bootstrap code with one listener thread and two workers will look like
public static void setupHTTPListeners()
{
ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newFixedThreadPool(1),
Executors.newFixedThreadPool(2)));
-----
-----
}
On the same context, one of the most popular read is here - The C10k problem.
Use ServerSocket(int port, int backlog); the backlog parameter is the maximum number of connections allowed.
I am new to multithreading & socket programming in Java. I would like to know what is the best way to implement 2 threads - one for receiving a socket and one for sending a socket. If what I am trying to do sounds absurd, pls let me know why! The code is largely inspired from Sun's tutorials online.I want to use Multicast sockets so that I can work with a multicast group.
class Server extends Thread
{
static protected MulticastSocket socket = null;
protected BufferedReader in = null;
public InetAddress group;
private static class Receive implements Runnable
{
public void run()
{
try
{
byte[] buf = new byte[256];
DatagramPacket pkt = new DatagramPacket(buf,buf.length);
socket.receive(pkt);
String received = new String(pkt.getData(),0,pkt.getLength());
System.out.println("From server#" + received);
Thread.sleep(1000);
}
catch (IOException e)
{
System.out.println("Error:"+e);
}
catch (InterruptedException e)
{
System.out.println("Error:"+e);
}
}
}
public Server() throws IOException
{
super("server");
socket = new MulticastSocket(4446);
group = InetAddress.getByName("239.231.12.3");
socket.joinGroup(group);
}
public void run()
{
while(1>0)
{
try
{
byte[] buf = new byte[256];
DatagramPacket pkt = new DatagramPacket(buf,buf.length);
//String msg = reader.readLine();
String pid = ManagementFactory.getRuntimeMXBean().getName();
buf = pid.getBytes();
pkt = new DatagramPacket(buf,buf.length,group,4446);
socket.send(pkt);
Thread t = new Thread(new Receive());
t.start();
while(t.isAlive())
{
t.join(1000);
}
sleep(1);
}
catch (IOException e)
{
System.out.println("Error:"+e);
}
catch (InterruptedException e)
{
System.out.println("Error:"+e);
}
}
//socket.close();
}
public static void main(String[] args) throws IOException
{
new Server().start();
//System.out.println("Hello");
}
}
First thing is first: your classes should start with a capital letter per the Java Naming Conventions:
Class names should be nouns, in mixed case with the first letter of
each internal word capitalized. Try to
keep your class names simple and
descriptive. Use whole words-avoid
acronyms and abbreviations (unless the
abbreviation is much more widely used
than the long form, such as URL or
HTML).
Second:
Try to break down the code into coherent sections and organize them around some common feature that you're dealing with... perhaps around the functionality or the model you're programming.
The (basic) model for the server is that the only thing it does is receive socket connections... the server relies on a handler to handle those connections and that's it. If you try to build that model it would look something like this:
class Server{
private final ServerSocket serverSocket;
private final ExecutorService pool;
public Server(int port, int poolSize) throws IOException {
serverSocket = new ServerSocket(port);
pool = Executors.newFixedThreadPool(poolSize);
}
public void serve() {
try {
while(true) {
pool.execute(new Handler(serverSocket.accept()));
}
} catch (IOException ex) {
pool.shutdown();
}
}
}
class Handler implements Runnable {
private final Socket socket;
Handler(Socket socket) { this.socket = socket; }
public void run() {
// receive the datagram packets
}
}
Third: I would recommend that you look at some existing examples.
Multi-threaded Client/Server Applications:
http://www.ase.md/~aursu/ClientServerThreads.html
Doug Lea:
http://www.developer.com/java/ent/article.php/3645111/Java-5s-BlockingQueue.htm (thanks to John)
http://gee.cs.oswego.edu/dl/cpj/index.html (still can't find the exact example, but it's there somewhere... if you feel brave look over his allcode.java file).
Concurrency in Practice examples:
http://www.javaconcurrencyinpractice.com/listings.html
Java Concurrency Tutorials:
http://java.sun.com/docs/books/tutorial/essential/concurrency/
Updated per comments:
OK Ravi, there are some big issues with your code and some minor issues with it:
I assume that the Receive class is your client... you should pull that out as a separate program (with its own main class) and run your server and multiple clients at the same time. Spawning a new "client thread" from your server for every new UDP package you send is a disturbing idea (big issue).
When you make your client application, you should make it run the receiving code in its own while loop (minor issue), e.g.:
public class Client extends Thread
{
public Client(/*..*/)
{
// initialize your client
}
public void run()
{
while(true)
{
// receive UDP packets
// process the UDP packets
}
}
public static void main(String[] args) throws IOException
{
// start your client
new Client().start();
}
}
You should only need just one thread per client and one thread per server (you technically don't even a separate thread in there since main has its own thread), so you might not find the ExecutorService that useful.
Otherwise your approach is correct... but I would still recommend that you check out some of examples.
Wanting to create threads in an application is not absurd! You won't need exactly 2 threads, but I think you're talking about 2 classes that implement the Runnable interface.
The threading API has gotten better since Java 1.5 and you don't need to mess with java.lang.Thread anymore. You can simply create a java.util.concurrent.Executor and submit Runnable instances to it.
The book Java Concurrency in Practice uses that exact problem - creating a threaded socket server - and walks through several iterations of the code to show the best way to do it. Check out the free sample chapter, which is great. I won't copy/paste the code here, but look specifically at listing 6.8.
It's a good thing Eclipse's history works even for a day back :) Thanks to that, I am able to give both Ravi a working example and Lirik his answer on leakage.
Let me first start of by stating that I have no clue what is causing this leak, but if I leave it long enough, it will fail on a OutOfMemoryError.
Second, I left the working code commented out for Ravi for a working basic example of my UDP server. The timeout was there to test how long my firewall would kill the receivers end (30 seconds). Just remove anything with the pool, and you're good to go.
So here is, a working but leaking version of my example threaded UDP server.
public class TestServer {
private static Integer TIMEOUT = 30;
private final static int MAX_BUFFER_SIZE = 8192;
private final static int MAX_LISTENER_THREADS = 5;
private final static SimpleDateFormat DateFormat = new SimpleDateFormat("yyyy-dd-MM HH:mm:ss.SSSZ");
private int mPort;
private DatagramSocket mSocket;
// You can remove this for a working version
private ExecutorService mPool;
public TestServer(int port) {
mPort = port;
try {
mSocket = new DatagramSocket(mPort);
mSocket.setReceiveBufferSize(MAX_BUFFER_SIZE);
mSocket.setSendBufferSize(MAX_BUFFER_SIZE);
mSocket.setSoTimeout(0);
// You can uncomment this for a working version
//for (int i = 0; i < MAX_LISTENER_THREADS; i++) {
// new Thread(new Listener(mSocket)).start();
//}
// You can remove this for a working version
mPool = Executors.newFixedThreadPool(MAX_LISTENER_THREADS);
} catch (IOException e) {
e.printStackTrace();
}
}
// You can remove this for a working version
public void start() {
try {
try {
while (true) {
mPool.execute(new Listener(mSocket));
}
} catch (Exception e) {
e.printStackTrace();
}
} finally {
mPool.shutdown();
}
}
private class Listener implements Runnable {
private final DatagramSocket socket;
public Listener(DatagramSocket serverSocket) {
socket = serverSocket;
}
private String readLn(DatagramPacket packet) throws IOException {
socket.receive(packet);
return new BufferedReader(new InputStreamReader(new ByteArrayInputStream(packet.getData())), MAX_BUFFER_SIZE).readLine();
}
private void writeLn(DatagramPacket packet, String string) throws IOException {
packet.setData(string.concat("\r\n").getBytes());
socket.send(packet);
}
#Override
public void run() {
DatagramPacket packet = new DatagramPacket(new byte[MAX_BUFFER_SIZE], MAX_BUFFER_SIZE);
String s;
while (true) {
try {
packet = new DatagramPacket(new byte[MAX_BUFFER_SIZE], MAX_BUFFER_SIZE);
s = readLn(packet);
System.out.println(DateFormat.format(new Date()) + " Received: " + s);
Thread.sleep(TIMEOUT * 1000);
writeLn(packet, s);
System.out.println(DateFormat.format(new Date()) + " Sent: " + s);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
if (args.length == 1) {
try {
TIMEOUT = Integer.parseInt(args[0]);
} catch (Exception e) {
TIMEOUT = 30;
}
}
System.out.println(DateFormat.format(new Date()) + " Timeout: " + TIMEOUT);
//new TestServer(4444);
new TestServer(4444).start();
}
}
btw. #Lirik, I witnessed this behavior first in Eclipse, after which I tested it from the command line. And again, I have NO clue what is causing it ;) sorry...
2 threads is fine. One reader another writer. Remember that with UDP you should not spawn new handler threads (unless what you're doing takes a long time), I recommend throwing the incoming messages into a processing Queue. The same for the send, have a send thread that blocks on an incoming Queue for UDP send.