TcpSockets do not connect - java

I am trying to establish a TCP connection between a laptop as a client and a pc as a server.
My goal is to use the server to send messages between two android devices. The server has a public IP address. To test the connection, I have written two simple Java classes:
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public ServerSocket welcome;
public Socket soc;
public int listeningPort = /* default port */;
public TcpServer() {
}
public static void main(String[] args) {
TcpServer ms = new TcpServer();
if(args.length > 0) {
ms.listeningPort = Integer.parseInt(args[0]);
}
ms.listen();
}
public void listen() {
try {
welcome = new ServerSocket(listeningPort);
System.out.println(">>> listening on port " + listeningPort + " <<<");
soc = welcome.accept();
System.out.println(">>> got a new connection from "
+ soc.getInetAddress().toString() + " <<<");
while (true) {
try {
byte b[] = new byte[1024];
soc.getInputStream().read(b, 0, 1);
System.out.print((char) (b[0]));
} catch (Exception e) {
System.err.println(e);
}
}
} catch (Exception e) {
System.err.println(e);
}
}
}
import java.net.Socket;
public class TcpSendClient {
private String serverIp = /* some ip */;
public int port = /* default port */;
private SendThread st;
public TcpSendClient() {
}
public static void main(String[] args) {
TcpSendClient client = new TcpSendClient();
if(args.length > 0) {
client.port = Integer.parseInt(args[0]);
}
client.send();
}
public void send() {
System.out.println("Try to connet to " + serverIp + " via Port" + port);
st = new SendThread(serverIp, port);
st.start();
}
class SendThread extends Thread {
private Socket soc;
public SendThread(String theIp, int thePort) {
try {
soc = new Socket(theIp, thePort);
} catch (Exception e) {
System.err.println(e);
}
}
public void run() {
try {
while (true) {
String toSend = "Hello ";
soc.getOutputStream().write(toSend.getBytes());
Thread.sleep(800);
System.out.println("sent");
}
} catch (Exception e) {
System.err.println(e);
}
}
}
}
When I run both Java files on the server pc, the connection works fine. It also worked if I set up a local Wi-Fi with one laptop and connect to it using another laptop.
But, when I run the client file from a laptop connected to the internet, I am not able to get a connection.
In the firewall on the Server, I opened a number of ports for the connection and the laptop I use as a client has the firewall disabled.
Apart from the firewall, I do not really know what to look into in order to get the connection running. Any ideas as to the cause of my problem and a solution?

I found the solution: The windows firewall was still blocking the ports for Java. It took me a little longer to figure this out, because I was not registered as admin on that pc and could not see the rules.

Related

Why I try to run Client.jar on Another Computer but receive Connection refused" or "Connection timed out

I spent more than one day , but still can't figure out how can I resolve the problem. Every time I shut down the firewall on my server, my other computer can successfully run Client.jar.
I check the firewall on my server PC. I am sure I opened the port "4888" and "6151", but still can't run normally.
I don't know how "W.getSocketFactory()" works.
System.out.println("創造"+ W.getSocketFactory()); → 創造 null (Is it an issue?)
Is there some problems on my codes or somethings?
Below is my server code:
public class RemoteServer extends UnicastRemoteObject implements MyRemote{
public static void main(String[] args)
{
try {
RMILocalSocketFactory W = new RMILocalSocketFactory(6151);
System.out.println("創造"+ W.getSocketFactory());
RMISocketFactory.setSocketFactory(W);
LocateRegistry.createRegistry(4888);
System.setProperty("java.rmi.server.hostname","175.183.49.139");
MyRemote Server = new RemoteServer();
Naming.rebind("rmi://175.183.49.139:4888/Remote_Hello!", Server);
} catch (Exception e) {
e.printStackTrace();
}
}
RemoteServer() throws RemoteException {}
public String SayHello()
{
System.out.println("RMI Connection");
return "you Connected Server\n" + "Server says , Hey!";
}
}
class RMILocalSocketFactory extends RMISocketFactory {
private int dataPort;
public RMILocalSocketFactory(int dataPort1){
this.dataPort = dataPort1;
}
public Socket createSocket(String host, int port) throws IOException {
String a = "175.183.49.139";
Socket check = new Socket(a = host, port);
return check;
}
public ServerSocket createServerSocket(int port) throws IOException {
return new ServerSocket(port);
}
}
(Client) the one part of code:
try {
LocateRegistry.getRegistry(4888);
MyRemote Service = (MyRemote)Naming.lookup("rmi://175.183.49.139:4888/Remote_Hello!");
String Say= Service.SayHello();
Area.append(Say);
} catch (Exception e) {
e.printStackTrace();
}
```[Problem Picture:][1]
[1]: https://i.stack.imgur.com/LkK5T.jpg
I resolved my problem by myself.
I finally found my java.exe on firewall is blocked.
That is the reason why I can't receive another request while firewall is on.
And make sure both port must be open on firewall as well.

Multi-Client Server in Java, Maybe threads not running properly or i dont know , cant find out why

I'm programming a server in java that broadcasts the Date() function each second to the clients. The problem is that it worked for only one client but as soon as I started making modifications for multi-client support it broadcasts the Date() only once and then stops, as if the function is being called only once. I can not find what I'm doing wrong so I will just paste the code and hopefully someone will spot the mistake. I searched online but only to end up more confused than I started. For Client program I use the tellnet terminal app for windows.
public class Server
{
private ServerSocket SERVER;
private int PORT;
private Socket CLIENT;
public Server()
{
PORT = 8818;
try
{
SERVER = new ServerSocket(PORT);
System.out.println("Server started on port: " + PORT);
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
public void On() throws IOException
{
while(true)
{
CLIENT = SERVER.accept();
new ClientHandler(CLIENT).start();
}
}
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public class ClientHandler extends Thread
{
private Socket CLIENT;
private OutputStream out;
public ClientHandler(Socket CLIENT)
{
System.out.println("Accepted Connection from: " + CLIENT.getInetAddress());
this.CLIENT = CLIENT;
}
public void run()
{
try
{
out = CLIENT.getOutputStream();
out.write(("Time now is: " + new Date() + "\n").getBytes());
sleep(1000);
}
catch(Exception e)
{
System.out.println(CLIENT.getInetAddress() + " has left the session");
try
{
out.close();
CLIENT.close();
}
catch(IOException j)
{
System.out.println("Unexpected Error");
System.exit(-1);
}
}
}
}
Your modifications nearly worked - below is a running version with only minor modifications from your code.
A part of your modifications you unintentionally removed the while loop in the run function, which means the Date() function is in fact only called once. To see this, remove the while loop in run() and after the Date is printed (in the telnet window) the message "Done with the run function." is printed.
I added an identifier to each client which is printed with the date. The static cnt class field makes sure that each client has a different id.
I started separate clients in separate command prompt terminals using
telnet localhost 8818 such that they were running at the same time. At the bottom is the output from the 3rd client.
I did switch the code to camelCase convention (start variables with a lower case letter and capitalizing each new word) since all CAPS is usually reserved for constants and the change made the code easier to read for me.
public class Server
{
private ServerSocket server;
private int port;
private Socket client;
public Server()
{
port = 8818;
try
{
server = new ServerSocket(port);
System.out.println("Server started on port: " + port);
}
catch(IOException e)
{
System.out.println(e.getMessage());
}
}
public void on() throws IOException
{
while(true)
{
client = server.accept();
new ClientHandler(client).start();
}
}
}
public class ClientHandler extends Thread {
private Socket client;
private OutputStream out;
private int id;
private static int cnt=0;
public ClientHandler(Socket client) {
System.out.println("Accepted Connection from: " + client.getInetAddress());
this.client = client;
id=cnt;
cnt++;
}
public void run() {
try {
out = client.getOutputStream();
while (true) {
out.write(("Client " + id + ": Time now is: " + new Date() + "\n").getBytes());
sleep(1000);
}
} catch (Exception e) {
System.out.println(client.getInetAddress() + " has left the session");
try {
out.close();
client.close();
} catch (IOException j) {
System.out.println("Unexpected Error");
System.exit(-1);
}
}
System.out.println("Done with the run function.");
}
}
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
Server s = new Server();
s.on();
}
}

DataInputStream not Receiving Data After Flushing DataOutputStream

So, I'm fairly new to sockets and data streams... And I am absolutely baffled by this issue I'm having. I've searched for hours trying to find a solution, assuming that other people might have had the same issue I'm having, but I've found absolutely nothing helpful so far.
I'm writing a very simple multithreaded server/client program that is supposed to open a serverSocket, and accept connections from clients, storing them in a simple arraylist (I'll change the storage process once I actually get messages to send), and then a message handler thread parses the list, and checks if a user has written to the server. If the user has written something, the program then displays the resulting message to the console. My program successfully writes to the server socket through the DataOutputStream, but when I attempt to read from the corresponding DataInputStream on the server side, it says the stream is empty, and my program will continue to loop. I've checked that the DataOutputStream receives the data through DataOutputStream.size(), and that the DataInputStream I am attempting to read data from corresponds to the correct DataOutputStream I mentioned before.
User Code:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
public class User {
private String hashID;
private Socket connection;
private static int hashVal = 0;
DataInputStream consoleInputStream;
String consoleInput = "";
public User(Socket conn) throws SocketException {
hashID = hashUserKey();
connection = conn;
connection.setSoTimeout(1500);
consoleInputStream = new DataInputStream(System.in);
}
private static String hashUserKey() { //placeholder for now
hashVal++;
return("Guest" + hashVal);
}
public Socket getSocket() {
return this.connection;
}
public String getID() {
return this.hashID;
}
public boolean disconnect() {
try {
consoleInputStream.close();
connection.close();
return true;
} catch (IOException e) {
System.err.println(hashID + " was unable to successfully disconnect");
return false;
}
}
public void startConnection() {
new Thread() {
#Override
public void run() {
while(!connection.isClosed()) {
try {
consoleInput = consoleInputStream.readLine();
if(consoleInput != null || consoleInput != "") {
writeToServer(consoleInput);
}
} catch (IOException e) {
System.err.println("Was not able to read console input");
}
}
System.out.println("You were disconnected, have a nice day!");
return;
}
}.start();
}
private boolean writeToServer(String toWrite) {
try {
String msg = hashID + ">>>: " + toWrite;
DataOutputStream outStream = new DataOutputStream(connection.getOutputStream());
outStream.writeUTF(toWrite + "\r\n");
outStream.flush();
consoleInput = "";
System.out.println(msg + "\t was written to " + connection.getInetAddress() + ":" + connection.getPort());
return true;
} catch (IOException e) {
System.err.println(hashID + " was unable to write to server");
return false;
}
}
#Override
public boolean equals(Object o) {
User t = (User) o;
if(t.hashID == this.hashID) {
return true;
}
return false;
}
}
Server Code:
import java.net.*;
import java.io.*;
import java.util.*;
public class TestServer {
private static ServerSocket server;
private static TestLogger logger;
private static Thread serverHandlerThread;
private static Thread messageHandlerThread;
private static ArrayList<User> users;
private static volatile boolean hasBeenStopped = false;
public static boolean startServer(int port) {
logger = new TestLogger();
logger.log("Attempting to create default shutdown behavior for server");
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
if(!hasBeenStopped) {
logger.warn("Server was shut down without running stopServer(), running by default");
stopServer();
}
}
}
);
logger.log("Shutdown behaivor created. Now attempting to set up user database"/*TODO create a real database*/);
users = new ArrayList<User>();
logger.log("Attempting to start server");
try {
server = new ServerSocket(port);
logger.log("Server successfully started at " + server.getInetAddress() + ":" + server.getLocalPort() +", now attempting to start user connection handler");
serverHandlerThread = new Thread() {
#Override
public void run() {
this.setName("serverHandlerThread");
while(!server.isClosed()) {
try {
Socket temp = server.accept();
logger.log("Connection accepted from " + temp.getInetAddress());
System.out.println("Connection accepted from " + temp.getInetAddress());
startUserConnection(new User(temp));
} catch (SocketException e) {
logger.warn("Server was closed while in accept phase");
} catch (IOException e) {
e.printStackTrace();
}
}
logger.log(this.getName() + " was stopped, server socket was closed successfully");
return;
}
};
serverHandlerThread.start();
logger.log("Server thread successfully started, listening for connections on: " + server.getInetAddress().toString() + ":" + port);
logger.log("Attempting to start message handler thread to read user inputs");
messageHandlerThread = new Thread() {
#Override
public void run() {
this.setName("messageHandlerThread");
while(!server.isClosed()) {
if(users.isEmpty()) {
continue;
}
for(int i = 0; i < users.size(); i++) {
User temp = users.get(i);
try {
System.out.println(new DataInputStream(temp.getSocket().getInputStream()).readUTF());
} catch (IOException e) {
System.err.println("Nothing to read from client: " + temp.getID());
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
};
messageHandlerThread.start();
return true;
} catch (IOException e) {
logger.error("Could not bind server socket to port.");
return false;
}
}
public static boolean stopServer() {
logger.log("Started shut down process");
if(serverHandlerThread == null || !serverHandlerThread.isAlive()) {
logger.warn("Thread has not been started yet or has already been killed");
return false;
}
else {
stopAllUserConnections();
try {
server.close();
hasBeenStopped = true;
while(serverHandlerThread.isAlive()) {
}
logger.log("Server was successfully shut down");
return true;
} catch (IOException e) {
logger.error("Could not close server socket");
return false;
}
}
}
private static void startUserConnection(User user) {
logger.log("Connected new user from " + user.getSocket().getInetAddress());
users.add(user);
System.out.println(user.getID() + " was added to list");
user.startConnection();
}
private static boolean stopUserConnection(User user) {
logger.log("Attempting to disconnect user, address: " + user.getSocket().getInetAddress());
for(User u : users) {
if(u.equals(user)) {
u.disconnect();
return true;
}
}
logger.warn("Could not find user with address: " + user.getSocket().getInetAddress());
return false;
}
private static boolean stopAllUserConnections() {
logger.log("Attempting to disconnect all users from the server");
if(users.isEmpty()) {
logger.warn("No users available to disconnect");
return false;
}
for(User u : users) {
u.disconnect();
}
users.clear();
return true;
}
public static void main(String args[]) {
startServer(*the_port*);
Client c = new Client();
c.connect("0.0.0.0", *the_port*);
}
}
Client Code:
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public boolean connect(String serverName, int port) {
try {
System.out.println("Attempting to connect");
Socket sock = new Socket(serverName, port);
System.out.println("Connected");
return true;
} catch (UnknownHostException e) {
System.err.println("Could not resolve " + serverName + ":" + port);
}
catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
So as I said above, this works fine up until I attempt to read the data written to the server. No matter what I do, the server's call to readUTF() on the socket always throws an IOException and checking the bytes ready to read by using DataInputStream.available() returns 0 as well. My sample output from my most recent run is as follows:
Attempting to connect
Connected
Connection accepted from *the_address*
Guest1 was added to list
Nothing to read from client: Guest1
Nothing to read from client: Guest1
Nothing to read from client: Guest1
test
Guest1>>>: test was written to *the_address:another_port*
Nothing to read from client: Guest1
Nothing to read from client: Guest1
Nothing to read from client: Guest1
I know my code may be terribly optimized, and I'll work on fixing that later, but right now, all I want to know is why my DataInputStream is empty after flushing the corresponding DataOutputStream, and how I can successfully send UTF data between them.

restricting number of connections in java socket server

I have created a Java socket server which creates a socket server on a specified port and then spawns a RecordWriter object to perform some operation on the data stream obtained from each connection.
I start the program with port as 61000 and numthreads as 2.
I also started 3 clients to connect to it.
On the client side I could see that all 3 of them connected to the receiver however, the receiver logs indicated only two of them connected.
netstat -an|grep 61000|grep -i ESTABLISHED
indicated total 6 connections as the client and server are being run on the same machine.
My doubts are:
Why does the client log for the third time show that it could connect to the program on 61000 while I am using the backlog of 2. Also Executors.newFixedThreadPool(numThreads); is allowing only 2 clients to be connected.
Although the server.accept happens in the MyWriter.java and there is no indication in logs that the 3rd client could connect, why does netstat show this as an Established connection
Here are my codes:
MyReceiver.java
package com.vikas;
import java.net.ServerSocket;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyReceiver{
protected int serverPort = -1;
protected int numThreads = -1;
protected boolean isStopped = false;
protected Thread runningThread = null;
protected ExecutorService threadPool = null;
protected static Logger logger = LogManager.getLogger(MyReceiver.class);
protected static ServerSocket serverSocket = null;
protected static Map<String, String> mapConnections = new ConcurrentHashMap<String, String>();
public MyReceiver(int port){
this.serverPort = port;
}
public void run(int numThreads){
this.threadPool = Executors.newFixedThreadPool(numThreads);
try {
logger.info("Starting server on port " + this.serverPort);
MyReceiver.serverSocket = new ServerSocket(this.serverPort, numThreads);
} catch (IOException e) {
//throw new RuntimeException("Cannot open port " + this.serverPort, e);
logger.error("Cannot open port " + this.serverPort, e);
}
while(!isStopped()){
this.threadPool.execute(new MyWriter());
}
if(MyReceiver.mapConnections.isEmpty()){
this.threadPool.shutdown();
//System.out.println("Server Stopped after shutdown.") ;
logger.info("Server Stopped after shutdown.");
}
}
public synchronized boolean isStopped() {
return this.isStopped;
}
public synchronized void stop(){
this.isStopped = true;
try {
MyReceiver.serverSocket.close();
} catch (IOException e) {
//throw new RuntimeException("Error closing server", e);
logger.error("Error closing server", e);
}
}
public static void main(String[] args) {
if(args.length != 2){
System.out.println("Number of input arguements is not equal to 4.");
System.out.println("Usage: java -cp YOUR_CLASSPATH -Dlog4j.configurationFile=/path/to/log4j2.xml com.vikas.MyReceiver <port> <number of threads>");
System.out.println("java -cp \"$CLASSPATH:./MyReceiver.jar:./log4j-api-2.6.2.jar:./log4j-core-2.6.2.jar\" -Dlog4j.configurationFile=log4j2.xml com.vikas.MyReceiver 61000 2");
}
int port = Integer.parseInt(args[0].trim());
int numThreads = Integer.parseInt(args[1].trim());
final MyReceiver myConnection = new MyReceiver(port, topic, brokers);
myConnection.run(numThreads);
/*Thread t = new Thread(myConnection);
t.start();*/
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
//e.printStackTrace();
logger.error("Something went wrong", e);
}
//System.out.println("Stopping Server");
Runtime.getRuntime().addShutdownHook(new Thread()
{
#Override
public void run()
{
logger.info("SocketServer - Receive SIGINT!!!");
logger.info("Stopping Server");
if(!myConnection.isStopped()){
myConnection.stop();
}
logger.info("Server Stopped successfully");
try
{
Thread.sleep(1000);
}
catch (Exception e) {}
}
});
//myConnection.stop();
}
}
MyWriter.java
package com.vikas;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.Socket;
import java.util.Properties;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyWriter implements Runnable{
protected String topic = null;
protected String brokers = null;
protected static Logger logger = LogManager.getLogger(MyWriter.class);
public MyWriter () {
}
public void run() {
while(!MyReceiver.serverSocket.isClosed()){
Socket server = null;
try {
server = MyReceiver.serverSocket.accept();
//System.out.println("Just connected to " + server.getRemoteSocketAddress());
logger.info("Just connected to " + server.getRemoteSocketAddress());
MyReceiver.mapConnections.put(server.getRemoteSocketAddress().toString().trim(), "");
//change for prod deployment //change implemented
String key = null;
String message = null;
char ch;
StringBuilder msg = new StringBuilder();
int value = 0;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(server.getInputStream()));
while((value = in.read()) != -1){
ch = (char)value;
if(ch == 0x0a){
//msg.append(ch);
//System.out.println(msg);
message = msg.toString().trim();
//code change as part of testing in prod
if(message.length() != 0){
//do something
msg.setLength(0);
}
else{
logger.error("Blank String received");
msg.setLength(0);
}
}
else{
msg.append(ch);
}
}
logger.info("Closing connection for client :" + server.getRemoteSocketAddress());
//System.out.println("Closing connection for client :" + this.getClientSocket().getRemoteSocketAddress());
server.close();
MyReceiver.mapConnections.remove(server.getRemoteSocketAddress());
} catch (IOException e) {
//report exception somewhere.
//e.printStackTrace();
logger.error("Something went wrong!!", e);
}
finally{
producer.close();
}
} catch (IOException e) {
if(MyReceiver.serverSocket.isClosed()) {
//System.out.println("Server was found to be Stopped.");
logger.error("Server was found to be Stopped.");
logger.error("Error accepting client connection", e);
break;
}
}
}
}
}
The backlog parameter of the ServerSocket constructor restricts the size of the incoming connection queue not the total number of times you are allowed to successfully call accept(). If you want to restrict the number of active connections you need to keep track of how many connections you've accepted then when you hit your threshold don't call accept() again until at least one of the active connections has been closed.
while(!MyReceiver.serverSocket.isClosed()){
Socket server = null;
try {
server = MyReceiver.serverSocket.accept();
//System.out.println("Just connected to " + server.getRemoteSocketAddress());
logger.info("Just connected to " + server.getRemoteSocketAddress());
MyReceiver.mapConnections.put(server.getRemoteSocketAddress().toString().trim(), "");
if (activeConnections == maxConnections) break; // exit accept loop

Java Server with Multiclient communication.

I'm making a game for an assignment. I have a server and multiclient set up in Java and we're using MVC. I need to have a client send their name to the server and then when two players are present I need to send both names back to the clients along with which player number they are (player one or player two). I don't get how I could tell which thread the information is coming from or which thread the information is getting sent to so not all players think they are player one. Thanks.
Here I am sharing you a nice Chat Program having one server that is communicating with multiple clients using TCP protocol as per your requirement.
Program contains:
Each client is informed wherever a new client is added along with their name and position.
It also checks for existing names. Program doesn't allow multiple clients using same name.
Use this program as initial starter for your game. Please let me know if you want to add new functionality in the program.
Here is the code (see code comments for more clarification):
Note: replace host name in LiveChatClient.java file before running this program at port no 1234
Steps to run the program:
first run LiveChatServer only for single time
then run LiveChatClient for multiple clients as many as you want to add
Opcode.java:
Operation code that is used to set a client-server communication protocol
package com.chat;
/**************** an interface to define different operation code **************/
public interface Opcode {
int CLIENT_CONNECTEING = 1;
int CLIENT_CONNECTED = 2;
}
LiveChatServer.java:
Single server that is controlling multiple clients
package com.chat;
/************************ Live Chat Server *******************/
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.LinkedHashMap;
public class LiveChatServer {
// Connection state info
private static LinkedHashMap<String, ClientThread> clientInfo = new LinkedHashMap<String, ClientThread>();
// TCP Components
private ServerSocket serverSocket;
// Main Constructor
public LiveChatServer() {
startServer();// start the server
}
public void startServer() {
String port = "1234";
try {
// in constractor we are passing port no, back log and bind address whick will be local
// host
// port no - the specified port, or 0 to use any free port.
// backlog - the maximum length of the queue. use default if it is equal or less than 0
// bindAddr - the local InetAddress the server will bind to
int portNo = Integer.valueOf(port);
serverSocket = new ServerSocket(portNo, 0, InetAddress.getLocalHost());
System.out.println(serverSocket);
System.out.println(serverSocket.getInetAddress().getHostName() + ":"
+ serverSocket.getLocalPort());
while (true) {
Socket socket = serverSocket.accept();
new ClientThread(socket);
}
} catch (IOException e) {
System.out.println("IO Exception:" + e);
System.exit(1);
} catch (NumberFormatException e) {
System.out.println("Number Format Exception:" + e);
System.exit(1);
}
}
public static HashMap<String, ClientThread> getClientInfo() {
return clientInfo;
}
// *********************************** Main Method ********************
public static void main(String args[]) {
new LiveChatServer();
}
}
LiveChatClient.java:
Multiple clients talking to each other via server
package com.chat;
/************************ Live Chat Client *******************/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
public class LiveChatClient {
private String chatName;// current user's chat name(max 7 char if greater than show as 6
// char+...
private String serverAddress;
// TCP Components
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public LiveChatClient() {
initHostName();
runClient();// have fun
}
public void initHostName() {
try {
//replace host name with your computer name or IP address
serverAddress = "[hostname]";
if (serverAddress == null)
System.exit(1);
serverAddress = serverAddress.trim();
if (serverAddress.length() == 0)// empty field
{
System.out.println("Server IP Address or Name can't be blank.");
initHostName();
return;
}
System.out.println("Trying to connect with server...\nServer IP Address:"
+ serverAddress);
// create socket
InetAddress inetAddress = InetAddress.getByName(serverAddress);
if (!inetAddress.isReachable(60000))// 60 sec
{
System.out
.println("Error! Unable to connect with server.\nServer IP Address may be wrong.");
System.exit(1);
}
initPortNo();
} catch (SocketException e) {
System.out.println("Socket Exception:\n" + e);
initHostName();
return;
} catch (IOException e) {
initHostName();
return;
}
}
public void initPortNo() {
try {
String portNo = "1234";
portNo = portNo.trim();
if (portNo.length() == 0)// empty field
{
System.out.println("Server port No can't be blank.");
initPortNo();
return;
}
System.out.println("Trying to connect with server...\nServer Port No:" + portNo);
socket = new Socket(serverAddress, 1234);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
} catch (IOException e) {
System.out.println("IO Exception:\n" + e);
initPortNo();
return;
}
}
public void sendChatName() throws IOException {
System.out.println("Enter your name:");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String name = br.readLine();
if (name == null)
System.exit(1);
// title case (get only first 9 chars of chat name)
name = name.trim();
if (name.equalsIgnoreCase("All")) {
System.out.println("This name is already reserved. Try different one.");
sendChatName();
return;
}
if (name.length() == 0) {
System.out.println("Please enter your chat name.");
sendChatName();
return;
}
if (name.length() == 1)
chatName = String.valueOf(name.charAt(0)).toUpperCase();
if (name.length() > 1 && name.length() < 10)
chatName = String.valueOf(name.charAt(0)).toUpperCase()
+ name.substring(1).toLowerCase();
else if (name.length() > 9)
chatName = String.valueOf(name.charAt(0)).toUpperCase()
+ name.substring(1, 10).toLowerCase();
// sending opcode first then sending chatName to the server
out.println(Opcode.CLIENT_CONNECTEING);
out.println(chatName);
}
public void runClient() {
try {
sendChatName();
while (true) {
int opcode = Integer.parseInt(in.readLine());
switch (opcode) {
case Opcode.CLIENT_CONNECTEING:
// this client is connecting
boolean result = Boolean.valueOf(in.readLine());
if (result) {
System.out
.println(chatName + " is already present. Try different one.");
runClient();
}
break;
case Opcode.CLIENT_CONNECTED:
// a new client is connected
Integer totalClient = Integer.valueOf(in.readLine());
System.out.println("Total Client:" + totalClient);
for (int i = 0; i < totalClient; i++) {
String client = in.readLine();
System.out.println((i + 1) + ":" + client);
}
break;
}
}
} catch (IOException e) {
System.out.println("Client is closed...");
}
}
// *********************************** Main Method ********************
public static void main(String args[]) {
new LiveChatClient();
}
}
ClientThread.java:
Multiple thread started by server one for each client and containing information about all connected clients
package com.chat;
/************************ Client Thread *******************/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.HashMap;
public class ClientThread implements Runnable {
// TCP Components
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private String chatName;
// seperate thread
private Thread thread;
// boolean variable to check that client is running or not
private volatile boolean isRunning = true;
// opcode
private int opcode;
private HashMap<String, ClientThread> clientInfo = new HashMap<String, ClientThread>();
public ClientThread(Socket socket) {
try {
this.socket = socket;
this.clientInfo = LiveChatServer.getClientInfo();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
thread = new Thread(this);
thread.start();
} catch (IOException e) {
System.out.println(e);
}
}
public void run() {
try {
while (isRunning) {
if (!in.ready())
continue;
opcode = Integer.parseInt(in.readLine());// getting opcode first from client
switch (opcode) {
case Opcode.CLIENT_CONNECTEING:
chatName = in.readLine();
boolean result = clientInfo.containsKey(chatName);
out.println(Opcode.CLIENT_CONNECTEING);
out.println(result);
if (result)// wait for another chat name if already present
continue;
// send list of already online users to new online user
// for (Object user : clientInfo.keySet().toArray()) {
// out.println(Opcode.CLIENT_CONNECTED);
// out.println(user.toString());
// }
// put new entry in clientInfo hashmap
clientInfo.put(chatName, this);
int i = 0;
for (String key : clientInfo.keySet()) {
if (key.equals(chatName)) {
System.out.println(chatName + " added at " + (i + 1) + " position");
}
i++;
}
// tell other users about new added user and update their online users list
for (ClientThread client : clientInfo.values()) {
client.out.println(Opcode.CLIENT_CONNECTED);
client.out.println(clientInfo.size());
for (ClientThread client1 : clientInfo.values()) {
client.out.println(client1.chatName);
}
}
break;
}
}
// clsoe all connections
out.close();
in.close();
socket.close();
} catch (IOException e) {
System.out.println(e);
}
}
}
Here is the output when two client are added.
Server:
ServerSocket[addr=computerName/IPAddress,port=0,localport=1234]
computerName:1234
Abc added at 1 position
Xyz added at 2 position
Client 1:
Trying to connect with server...
Server IP Address:computerName
Trying to connect with server...
Server Port No:1234
Enter your name:
abc
Total Client:1
1:Abc
Total Client:2
1:Abc
2:Xyz
Client 2:
Trying to connect with server...
Server IP Address:computerName
Trying to connect with server...
Server Port No:1234
Enter your name:
xyz
Total Client:2
1:Abc
2:Xyz
Have 2 threads, one for user 1, and one for user 2. They should communicate to each other using a shared object and notify each other when events occur. Spawn thread 1 when first user connects and spawn thread 2 when second user connects.

Categories

Resources