This question already has an answer here:
Java Multiple threads for just 2 computers, how to do it in main
(1 answer)
Closed 7 years ago.
public class SOCKET_SERVER {
private JmailHelp JmailHELPER = new JmailHelp();
static int PORT = 444;
public static void main(String[] args) throws Exception {
SOCKET_SERVER SERVER = new SOCKET_SERVER();
SERVER.JmailHELPER.resetONN();
ServerSocket SRVSOCK = new ServerSocket(PORT);
//ArrayList<SocketStatus> OnlineUsers = new ArrayList<SocketStatus>();
Socket SOCK = SRVSOCK.accept();
//new ServerThread(SOCK).start();
SocketStatus a = new SocketStatus(SOCK, false);
//OnlineUsers.add(a);
//String action = "";
SERVER.ServerActionsHandler(SERVER, SRVSOCK, SOCK, a);
}//
}
forgive me if what i am giving is not enough don't hesitate to ask more if you can and want to try to help me
Well,
this is my socket server class ServerActionHandler is a method i created that takes as "input"(by BufferedReader) from the client a string and calls the right methods to serve the client.
for example he wants to login:
he(client) sends the string "login"
then server takes it as an "input" by the ServerActionHandler in a string called action, then recognise the the "login" and then calls the Acceptlogin method from the server class
Meanwhile client who send the "logi message" is calling the Dologin method from the client class
4.a loop of the ServerActionsHandler ends
5.A new loop starts asking the new action from the Client
my project works for A server and One client
I want to make it working for many clients
also something more I use JmailHELPER object
in almost all the methods of SOCKET_SERVER class(eg. login_accept,register_accept...)
in order to call some methods of it's class.
And SocketStatus keeps one variable if the certain socket which uses the Server is logged in or not
from what I know i have to make a ServerThreads class that extends Threads to handle more than one users.
What is the constructor and the run of that classmethod supposed to do
for example of A SocketThread I have this http://www.cdk5.net/ipc/programCode/TCPServer.java
thanks.
ok,
I know its funny but after a break of two hours I tried to find the solution for 3 minutes and i solved it(thats what i believe for now :P )
At least it is working on my pc for two clients so I will check it tommorow in more than one pc
Anyway I am posting the answer to my problem so that you can see it if you have a common problem
public static void main(String[] args) throws Exception {
SOCKET_SERVER SERVER = new SOCKET_SERVER();
SERVER.JmailHELPER.resetONN();
ServerSocket SRVSOCK = new ServerSocket(PORT);
while (true) {
Socket SOCK = SRVSOCK.accept();
SocketStatus a = new SocketStatus(SOCK, false);
new Thread() {
public void run() {
try {
SERVER.ServerActionsHandler(SERVER, SRVSOCK, SOCK, a);
} catch (Exception ex) {
Logger.getLogger(SOCKET_SERVER.class.getName()).log(Level.SEVERE, null, ex);
};
}
}.start();
}
}
Related
I am working on JADE (Java) project that connects Matlab by a TCP connection with client-server sockets. Here, JADE creates a server socket and Matlab creates a client socket. I am retrieving some data from Matlab to Java (JADE). The following is my code where I am calling Matlab by JADE through Agent. (1) The issue is I cannot re-run it without re-starting the program again. I believe that I require a multithread java instance with multithread Matlab instance that could connect and synchronize each other. However, I found that Matlab is a single thread. The program throws binding error.
WARNING: Error adding ICP jade.imtp.leap.JICP.JICPPeer#1dbb27d[Cannot bind server socket to localhost port 1099].
jade.core.AgentContainerImpl joinPlatform
SEVERE: Communication failure while joining agent platform: No ICP active
jade.core.IMTPException: No ICP active
I want to run it multiple times without manually re-starting. Here is my JADE code (took help from https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html):
public class MatlabComAgent extends Agent
{
ServerSocket srvr = null;
Socket skt = null;
BufferedReader in;
PrintWriter out;
String ip = "localhost";
String filePath;
int port = 1234;
protected void setup()
{
// Get arguments
Object[] args = getArguments();
filePath = (String) args[0];
// Create the TCP connection
try
{
// Create server and socket
srvr = new ServerSocket(port);
skt = srvr.accept();
// Create writer and reader to send and receive data
out = new PrintWriter(skt.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
}
catch (IOException e)
{
e.printStackTrace();
}
// Send a message to the tester to say its can start sending requests
sendMessage("Tester","","start-now",ACLMessage.INFORM);
// Run behavior
CommWithMatlab commWithMatlab = new CommWithMatlab();
addBehaviour(commWithMatlab);
} // End setup
Code for Matlab connection:
% Create TCP/IP object 't'. Specify server machine and port number.
% Open the connection with the server
t = tcpip('localhost', 1234);
set(t, 'InputBufferSize', 30000);
set(t, 'OutputBufferSize', 30000);
pause(0.1)
fopen(t);
disp('Connection with JADE established')
I found interesting notes on "socket server which allows multiple connections via threads and Java" Creating a socket server which allows multiple connections via threads and Java page, however, I am not able to do it completely what is said here. May be I am missing something here. (2) I am confused should I edit my Matlab code and/or JADE code for multi-threading.
Here is my code that I tried:
protected void setup()
{
// Get arguments
Object[] args = getArguments();
filePath = (String) args[0];
// Create the TCP connection
try
{
srvr = new ServerSocket(port);
Runnable connectionHandler = new ConnectionHandler(skt);
new Thread(connectionHandler).start();
}
catch (IOException e)
{
e.printStackTrace();
}
Here is new ConnectionHandler class:
public class ConnectionHandler implements Runnable {
private Socket sk=null; //initialize in const'r
BufferedReader in;
PrintWriter out;
public ConnectionHandler(ServerSocket skt) throws IOException
{
sk = skt.accept();
out = new PrintWriter(sk.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sk.getInputStream()));
}
public void run() {
try
{
// Create writer and reader to send and receive data
out = new PrintWriter(sk.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sk.getInputStream()));
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
But I got some erorr "java.lang.NullPointerException". Can someone help me to properly code it, what I am missing. Also, (3) this run() in ConnectionHandler class will be invoked automatically? I was confused so I create writer and reader inside Connectionhandler class and its run(). Can I simply make my MatlabComAgent class as multithread without adding any new class. I can make my class as
public class MatlabComAgent extends Agent implements Runnable
{....
....
}
Should I also put the following inside ConnectionHandler class?
// Send a message to the tester to say its can start sending requests
sendMessage("Tester","","start-now",ACLMessage.INFORM);
// Run behavior
CommWithMatlab commWithMatlab = new CommWithMatlab();
addBehaviour(commWithMatlab);
Here, CommWithMatlab class extends SimpleBehavior containg required actions that further passes commands from Matlab to PowerWorld (using another connection). One example is like:
class CommWithMatlab extends SimpleBehaviour
{
private static final long serialVersionUID = 8966535884137111965L;
#Override
public void action()
{
// Wait for a message from another agent requesting something
ACLMessage msg = blockingReceive();
// If this is to open a case
if(msg.getConversationId().equals(OPEN_CASE))
{
openCase(msg.getContent());
}
}
I can simple pass arguments to addagent() and can call runJade(). The following are my JADE run functions using agents:
//Runs JADE and starts the initial agents
public static void runJade() throws ControllerException
{
// Launch JADE platform
Runtime rt = Runtime.instance();
Profile p;
p = new ProfileImpl();
cController = rt.createMainContainer(p);
rt.setCloseVM(true);
// Launch Powerworld interface agent
addAgent(PWRWORLD_NAME, PWRWORLD_CLASS, null);
addAgent(PWRWORLD_TESTER_NAME, PWRWORLD_TESTER_CLASS, null);
//addAgent(PWRWORLD_TESTER_NAME2, PWRWORLD_TESTER_CLASS2, null);
}
private static void addAgent(String name, String type, String arg) throws ControllerException
{
Object[] argsObj = {arg};
AgentController ac = cController.createNewAgent(name, type, argsObj);
ac.start();
}
(4) I have a different program that also creates the same connection. When I try to run one program when other is running, it again throws binding error. However, these programs are completely separate. One program uses port 1234 and other 1239. However, system always assign local port to 1099 to both programs, hence throw binding error in this case.
Any help is appreciable!
Unfortunately, it is not possible to use matlabcontrol over a distributed network. I checked.
My question is about creating multiple TCP clients to multiple hosts using the same event loop group in Netty 4.0.23 Final, I must admit that I don't quite understand Netty 4's client threading business, especially with the loads of confusing references to Netty 3.X.X implementations I hit through my research on the internet.
with the following code, I establish a connection with a single server, and send random commands using a command queue:
public class TCPsocket {
private static final CircularFifoQueue CommandQueue = new CircularFifoQueue(20);
private final EventLoopGroup workerGroup;
private final TcpClientInitializer tcpHandlerInit; // all handlers shearable
public TCPsocket() {
workerGroup = new NioEventLoopGroup();
tcpHandlerInit = new TcpClientInitializer();
}
public void connect(String host, int port) throws InterruptedException {
try {
Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.remoteAddress(host, port);
b.handler(tcpHandlerInit);
Channel ch = b.connect().sync().channel();
ChannelFuture writeCommand = null;
for (;;) {
if (!CommandQueue.isEmpty()) {
writeCommand = ch.writeAndFlush(CommandExecute()); // commandExecute() fetches a command form the commandQueue and encodes it into a byte array
}
if (CommandQueue.isFull()) { // this will never happen ... or should never happen
ch.closeFuture().sync();
break;
}
}
if (writeCommand != null) {
writeCommand.sync();
}
} finally {
workerGroup.shutdownGracefully();
}
}
public static void main(String args[]) throws InterruptedException {
TCPsocket socket = new TCPsocket();
socket.connect("192.168.0.1", 2101);
}
}
in addition to executing commands off of the command queue, this client keeps receiving periodic responses from the serve as a response to an initial command that is sent as soon as the channel becomes active, in one of the registered handlers (in TCPClientInitializer implementation), I have:
#Override
public void channelActive(ChannelHandlerContext ctx) {
ctx.writeAndFlush(firstMessage);
System.out.println("sent first message\n");
}
which activates a feature in the connected-to server, triggering a periodic packet that is returned from the server through the life span of my application.
The problem comes when I try to use this same setup to connect to multiple servers,
by looping through a string array of known server IPs:
public static void main(String args[]) throws InterruptedException {
String[] hosts = new String[]{"192.168.0.2", "192.168.0.4", "192.168.0.5"};
TCPsocket socket = new TCPsocket();
for (String host : hosts) {
socket.connect(host, 2101);
}
}
once the first connection is established, and the server (192.168.0.2) starts sending the designated periodic packets, no other connection is attempted, which (I think) is the result of the main thread waiting on the connection to die, hence never running the second iteration of the for loop, the discussion in this question leads me to think that the connection process is started in a separate thread, allowing the main thread to continue executing, but that's not what I see here, So what is actually happening? And how would I go about implementing multiple hosts connections using the same client in Netty 4.0.23 Final?
Thanks in advance
So I created a basic client-server program in java. It starts out like this:
Client connects to Server
Server asks for Client's name
Client responds with name
Server greets Client
After this, Client speaks and the Server repeats the words back
I got this to work without too much trouble using this tutorial. The problem comes whenever I try to introduce multiple clients. I thought that it would work because I'm using multiple threads, however, the second clients just hangs until the first client quits and then it starts it work (the server does accept input from the second client, but it doesn't respond with anything until the first client quits).
Here is the code I'm using:
import java.net.*;
import java.io.*;
public class Server extends Thread {
private ServerSocket listener;
public Server(int port) throws IOException {
listener = new ServerSocket(port);
}
public void run() {
while(true) {
try {
Socket server = listener.accept();
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("What is your name?");
DataInputStream in = new DataInputStream(server.getInputStream());
String user_name = in.readUTF();
out.writeUTF("Hello "+user_name);
while(true) {
String client_message = in.readUTF();
out.writeUTF(client_message);
}
}
catch(IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int port = 6006;
try {
Thread t = new Server(port);
t.start();
} catch(IOException e) {
e.printStackTrace();
}
}
}
Can someone explain what I'm doing wrong?
I have looked at the using Runnable instead of Extends Thread, but I ran into even more problems there, so I want to try and work with this first.
Incoming connections are only handled by the line listener.accept();. But after you got a client connected, you're stuck in the while loop. You need to create a new Thread (or Runnable executed on an ExecutorService if you expect high load), and start it, then immediately accept the next connection.
In a nutshell, this is what is going wrong.
You are using exactly ONE thread as the server.
Blocking this thread when you call listener.accept()
This is what you need to do:
Create two classes
1: Server - Similar to what you have now, but instead of doing the actual work of acting as an echo server, it just spawns a new Thread which starts listening on a NEW PORT (which you can select randomly), and sends the client the address for this new port. The client will then get the new port number and would try to connect to the server on the new port.
2: The Echo thread - This starts a new listener on the port passed, and does the job of echoing to whoever is listening.
OR:
You start a UDP server rather than a TCP server, and all this will not matter then, but that is out of the purview of this specific question.
On my machine, the following code compiles within Eclipse but throws an exception within Netbeans. The error message says "Exception in thread "main" java.net.BindException: Address already in use".
What is the proper configuration within Netbeans to make this code compile? It seems like the problem has to do with the fact that I have two main functions. If I start running either one of the apps, the second will fail to start, throwing the exception posted above.
Server.java
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception {
Server myServ = new Server();
myServ.run();
}
public void run() throws Exception {
ServerSocket mySS = new ServerSocket(9999);
Socket SS_accept = mySS.accept();
InputStreamReader mySR = new InputStreamReader(SS_accept.getInputStream());
BufferedReader myBR = new BufferedReader(mySR);
String temp = myBR.readLine();
System.out.println(temp);
}
}
Client.java
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws Exception {
Client myCli = new Client();
myCli.run();
}
public void run() throws Exception {
Socket mySkt = new Socket("localhost", 9999);
PrintStream myPS = new PrintStream(mySkt.getOutputStream());
myPS.println("Hello server");
}
}
The problem is due to the fact that you left one instance of your server running and then started another one.
The way to achieve what I want is to right-click on the particular class (ex. Server.java) that I want to run and select "Run this file". This enables me to run only the Server app. Then, do the same process for the other file, Client.java.
However, Netbeans is somewhat confusing/deceiving in this particular circumstance. What Netbeans does is it runs the Server process, but labels that process as the name of the project (ex. MyTestNetworkingProject) and puts a run number on it, thus giving us MyTestNetworkingProject run #1 (it actually leaves out the #1 on the first process). Then, if I go to the Client.java file and select "Run this file", it generates a second process, MyTestNetworkingProject run #2. It then generates a second results window down at the bottom of the screen, as it generates these in new tabs as new processes get created.
Because of the nature of my specific code, what I wanted to see in my results window to confirm that my application was working was I wanted to observe the Server.java results window (which in this case is MyTestNetworkingProject run #1). Given my exact sequence of steps outlined above of running the different files, run #2 is the last run process and thus the tab on top, covering the run #1 tab. I can click on run #1 and see the results I was hoping to see in the console ("Hello server"), but I just have to know/remember that MyTestNetworkingProject run #1 represents the Server app and not the Client app.
Uncool, IMO.
If you write this in Windows OS,you can use "netstat -nao" to see which process use the 9999 port.If it is some unimportant process,you can kill this process.Otherwise you can change the port of the pragram.
I change the port address and it work for me in the Neat Beans IDE . This problem will come if we used the same port address for other one times . so to fix this error you have to change the port address and I am sure it will work
Server.java
public class SocServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(5001);
Socket client = server.accept();
DataOutputStream os = new DataOutputStream(client.getOutputStream());
os.writeBytes("Hello Sockets\n");
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client.java
public class SocClient {
public static void main(String[] args) {
try {
Socket socClient = new Socket("localhost", 5001);
InputStream is = socClient.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String receivedData = br.readLine();
System.out.println("Received Data: " + receivedData);
} catch (IOException e) {
e.printStackTrace();
}
}
}
refer above code and it works for me..
I did try the method catch and solved the problem.
I've recently gotten into trying to make server-client connections. I was able to make a 1 on 1 connection with no problems, but now i'm trying to make a server that accepts multiple clients and i'm running into a problem where i can't make the server listen to connections while there is one established... I'm not sure if i made myself clear but here's my code:
-The main loop that waits for connections:
public class ChatMultiServer {
public static void main(String []args){
int socknum = 124;
ServerSocket serverSocket;
Socket clientSocket;
while(true){
////opens socket
try{
System.out.println("Opening port...");
new ServerSocket(124).close();
serverSocket = new ServerSocket(socknum);
}catch(Exception e){System.out.println("Error 101 = failed to bind to port "+socknum+"."); break;}
//////accepts connection
try{
System.out.println("Waiting for connections...");
clientSocket = serverSocket.accept();
}catch(Exception e){System.out.println("Error 102 = failed to accept port "+socknum+"."); break;}
/////
try{
System.out.println("Initializing thread...");
new Thread(new CMSThread(clientSocket));
}catch(Exception e){System.out.println("Error 103 = failed to create thread."); break;}
try{
serverSocket.close();
}catch(Exception e){System.out.println("Error 105 = failed to close socket.");}
}
}
}
-The thread that handles the connections:
public class CMSThread extends Thread{
Socket socket;
BufferedReader in;
PrintWriter out;
String username;
char EOF = (char)0x00;
public CMSThread(Socket s){
socket = s;
run();
}
public void run(){
try{
System.out.println("Setting up streams...");
in = (new BufferedReader(new InputStreamReader(socket.getInputStream())));
out = new PrintWriter(socket.getOutputStream());
}catch(Exception e){System.out.println("Error 204 = failed to get streams");}
try{
out.print("Welcome! you can quit at any tyme by writing EXIT.\nLet me introduce myself, I'm 'testprogram 1', but that doesn't really matter since you'll do the talking.\nWhat's your name?"+EOF);
out.flush();
username = in.readLine();
out.print("<b>"+username+"</b>, that's a nice name.\nWell, i'll shut up now. Have fun talking to yourself while whoever is running the server observes your conversation.\n"+EOF);
out.flush();
}catch(Exception e){System.out.println("Are you effin kidding me!? -.- whatever... Error 666 = failed to chat.");}
}
}
My problem, once again, is that when the server gets a connection with a client(I'm using actionscript for the clients just because it's easier to make a GUI), it just waits until the thread is done running to start the loop again. I'm trying to make it loop at the same time as the thread handles the chat.
I was thinking maybe i needed to make a thread for the loop as well as the thread for handling the connection, but i'm not sure as to how i would go about doing that... Please let me know if my hypothesis was somewhat right, and if it was, some guidance towards the answer would be nice.
PS: I'm sorry if my code is a bit messy or if this is a stupid question, i haven't made a java program in a while...
You aren't actually starting your new Threads - you are just directly calling run(). As far as I can see, this means that you will be executing run() in the main thread that creates each CMSThread object.
To start a Thread, you have to call thread.start().
Also, I'm not sure why you are wrapping your CMSThread in another Thread - CMSThread extends Thread so it can be started in its own right. The wrapper Thread isn't being started either.
So you need:
new CMSThread(clientSocket).start();
and remove the run() call from the constructor of CMSThread