I'm doing a routing protocol packets between nodes and I have the following issue that I think is related threads, which are overwriting the variables, but do not know how to fix it. I have the code where the error is as follows:
pclass nodosVecinos extends Thread {
public static int port = 0;
String num_Nodo = "";
byte[] buf = new byte[10000];
public synchronized void run() {
DatagramPacket dP = new DatagramPacket(buf, buf.length);
DatagramSocket sK = null;
try {
System.out.println(port);
sK = new DatagramSocket(this.port);//<-- Problem
} catch (SocketException e) {
System.out.println("problem node "+num_Nodo);
e.printStackTrace();
}
System.out.println("Node "+ num_Nodo +" up!"); // Nodo 1 encendido!
while(true){
try {
sK.receive(dP);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Problem node , While");
}
System.out.println(buf.toString());
}
}
public nodosVecinos (int puerto){
port = puerto;
num_Nodo = Integer.toString(port);
num_Nodo = num_Nodo.substring(num_Nodo.length()-1,num_Nodo.length()); // 8001 => 1
}
public static void main(String args[]) {
}
}
i get out whit breackpoint :
8001 // <--- out in terminal
-1 // <--- Whit breackpoint and error.
I try write static the variable port but no go .
Thx for your help.
Edit:
The port is extern of synchronized , is class variable.
How do you start the threads?
Maybe "synchronized" is the problem. It causes that the whole method is executed before a new thread can start, but this method is infinite.
Related
This question already has an answer here:
(How) can I use ServerSocket to listen for UDP instead of TCP traffic?
(1 answer)
Closed 5 years ago.
Basically, I am writing a simple TCP-UDP multiclient GUI program. I can establish a TCP connection to the server but not an UDP connection. The server is listening in on port 4000. I have a comboBox on the GUI client which has elements TCP and UDP. If the user selects UDP and clicks Connect. Then it will attempt to establish a UDP connection by calling the UDPconnection method.
Here is my code for the client GUI:
public void UDPconnection()
{
try
{
done = false;
datagramSocket = new DatagramSocket(serverPort);
}
catch (SocketException e)
{
done = true;
System.out.println("Host not available");
}
}
Here is my code for the chat server:
public class chatServer2 implements Runnable {
private int clientCount = 0;
private ChatServerThread clients[] = new ChatServerThread[50];
private ServerSocket server = null;
Thread thread = null;
//same as version3
public chatServer2(int port){
try{
server = new ServerSocket(port);//step1
System.out.println("Started the server...waiting for a client");
start(); //the chatserver's start method that goes ahead and creates a new thread
}
catch(IOException e){
System.err.println("ERROR "+e.getMessage());
}
}
public void start(){
if(thread == null){
thread = new Thread(this);
thread.start();
}
}
#Override
public void run() {//same as version 3
while(thread !=null){
try{
System.out.println("Waiting for a client...");
//now we add a new Thread and accept a client
addThread(server.accept());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void addThread(Socket socket){
if(clientCount < clients.length){
clients[clientCount] = new ChatServerThread(this, socket);
try {
clients[clientCount].open();//open the stream for the ChatServerThread client
clients[clientCount].start();//start to run the ChatServerThread client
clientCount++;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public synchronized void handle(int ID, String input)
{
System.out.println(input);
if(input.equalsIgnoreCase("bye"))
{
remove(ID);//person said bye so remove them
}
else
{
System.out.println(input);
for (int i = 0; i < clientCount; i++)
{
clients[i].send("User: " + ID + ": " + input);
}
}
}
public synchronized void remove(int ID){
int position = findClient(ID);
if(position >=0){
ChatServerThread toRemove = clients[position];
if(position <clientCount-1){
for(int i= position+1; i <clientCount; i++){
clients[i-1] = clients[i];
}
clientCount--;
}
try {
toRemove.close();//close the person's that said bye connection
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private int findClient(int ID){
for(int i=0; i<clientCount; i++){
if(clients[i].getID() == ID){
return i;
}
}
return -1;//not in the array
}
public static void main(String [] args){
chatServer2 l = new chatServer2(4000);
}
}
There is no such thing as a 'UDP connection', for a start.
Failure to create a DatagramSocket on a specified port does not mean 'host not available'. Have a look at the exception message to see what it does mean.
UDP does not interoperate with TCP, and specifically not with Java ServerSockets. You need a DatagramSocket or DatagramChannel at both ends, and there is no connect phase: you just send datagrams back and forth.
I have been working with TCP server/client stuff for a while. I am actully good at UDP programming when it comes to connecting more than one user that is multiple clients. I tried to do the same on a TCP server that i made using Threads but whenever the Thread gets to this piece of code
String reader = (String)in.readObject();
an error is generated and the thread stops executing the code but the thread still runs the program keeping it alive.
Anyway here is the entire source code :
public class TestServer implements Runnable {
private Thread run, streams, connect, receive, send;
private ServerSocket socket;
private Socket conn;
private ObjectInputStream in;
private ObjectOutputStream out;
private boolean running, incomingMessage = false;
private int port;
public TestServer(int port) throws IOException {
this.port = port;
socket = new ServerSocket(port);
console("Server stated on : " + InetAddress.getLocalHost() + " : " + port);
run = new Thread(this, "Run");
run.start();
}
public void run() {
running = true;
connect();
receive();
}
private void connect() {
connect = new Thread("Connect") {
public void run() {
while(running) {
try {
conn = socket.accept();
} catch (IOException e) {
e.printStackTrace();
}
console("You are now connected" + conn.getInetAddress().toString() + " : " + conn.getPort());
try {
setupStreams();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}; connect.start();
}
private void setupStreams() throws IOException {
streams = new Thread("Streams") {
public void run() {
try {
console("Setting up Streams");
out = new ObjectOutputStream(conn.getOutputStream());
out.flush();
in = new ObjectInputStream(conn.getInputStream());
console("Streams are now setup");
incomingMessage = true;
receive.start();
} catch(IOException e) {
e.printStackTrace();
}
}
}; streams.start();
}
private void receive() {
receive = new Thread("Receive") {
public void run() {
while(incomingMessage) {
String message = "";
try {
message = (String) in.readObject();
//This is the only flaw the program
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
console("Client : " + message);
}
}
};
}
private void console(String message) {
System.out.println(message);
}
public static void main(String[] args) {
try {
new TestServer(1234);
} catch (IOException e) {
e.printStackTrace();
}
}
}
FYI am not new to this. The error is caused because the server starts receiving packets even when there are no packets to be received. But because the thread forces it to receive it, i generates the error in the thread and dont know any other way to counter this. So please help. Thanks in Advance.
You shouldn't need 2 threads per connection. One thread is all that's required. After the connection is accepted, pass it to a worker thread to start reading. This can be done in a while loop in the worker thread.
Even though the socket's input stream can be read, the ObjectInputStream() class is more sensitive. If there is any error, its state is corrupted and it can't be used.
while (true) {
try {
Object input = in.readObject();
message = (String) input;
} catch (IOException e) {
e.printStackTrace();
break; //unrecoverable
} catch (ClassNotFoundException e) {
e.printStackTrace();
break; //unrecoverable
}
console("Client : " + message);
}
It's a better design to use a specific message protocol instead of sending serialized Java objects. For example if you are sending Strings like your sample, an InputStreamReader can be used to convert bytes to characters more easily and with less error handling.
These resources would be helpful to you:
https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html#later
Java - Listening to a socket with ObjectInputStream
ObjectInputStream(socket.getInputStream()); does not work
I have to build a chat program.
There is the server class, the client class and two threads to write and receive messages.
the two threads should run in an infinite loop and check all the time if there is an input and print that input afterwards.
But my program works for just one round. So the server and the client can write one single message, afterwards it stops and does not check for another message. Why does the thread not start again from the begin when it's never interrupted? --> see the code beneath
I hope you know what my problem is, it's quite hard for me to describe.
Thread to read a new Message
public class MsgWriter extends Thread {
private Socket s;
public MsgWriter(Socket s){
this.s = s;
}
public void run(){
int i = 0;
OutputStream out = null;
PrintWriter writer;
Scanner input;
while(!interrupted()){
try{
synchronized(s){
input = new Scanner (System.in);
out = s.getOutputStream();
writer = new PrintWriter(out);
String toserver = input.nextLine();
writer.write(toserver);
writer.flush();
System.out.println("me: " + toserver);
}
try {
Thread.sleep((int) (100 * Math.random()));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}catch(Exception e) {
}
}
}
}
Thread to check if there is a new message and prints it.
public class MsgReader extends Thread {
Socket s;
public MsgReader(Socket s){
this.s = s;
}
public void run() {
int i = 0;
while (!interrupted()) {
try{
synchronized(s){
InputStream in = s.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String s = null;
while((s=reader.readLine()) != null){
System.out.println("d");
}
}
try {
Thread.sleep((int) (100 * 1));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}catch (Exception e){
}
}
}
}
The Server class starts a new server and waits for a client, afterwards it starts the two threads. The same with the client class, it connects to the server and starts the threads.
You're probably thowing an exception somewhere. In your catch blocks, print the error.
try {
} catch (Exception e) {
System.out.println("Error: " + e);
}
Hi I am trying out java multicast.
I have a WIFI router at - 10.0.0.1 (gateway)
and two nodes:
Node_1 - 10.0.0.4
Node_2 - 10.0.0.3
My IP Multicast sender looks like:
private static class Sender extends Thread
{
// Create the socket but we don't bind it as we are only going to send data
private MulticastSocket s;
private static int senderPort = 15000;
private static String group = "225.4.5.6";
public Sender() throws IOException
{
s = new MulticastSocket(senderPort);
s.setInterface(InetAddress.getLocalHost());
s.joinGroup(InetAddress.getByName(group));
}
#Override
public void run() {
Integer data = 1;
while(true)
{
try {
s.send(new DatagramPacket(data.toString().getBytes(), data.toString().getBytes().length, InetAddress.getByName(group), senderPort));
Thread.sleep(3000);
data++;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
System.out.println("Sender - UnknownHostException");
}catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Sender - IOException");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
And my IP Multicast receiver looks like:
private static class Receiver extends Thread
{
private MulticastSocket s;
private static int receiverPort = 15000;
private static String group = "225.4.5.6";
public Receiver() throws IOException
{
s = new MulticastSocket(receiverPort);
s.setInterface(InetAddress.getLocalHost());
s.joinGroup(InetAddress.getByName(group));
}
#Override
public void run() {
while (true)
{
byte buf[] = new byte[1024];
DatagramPacket pack = new DatagramPacket(buf, buf.length);
try {
System.out.println("Receiver waiting for data");
s.receive(pack);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.write(pack.getData(),0,pack.getLength());
System.out.println();
}
}
}
When I have both the Sender and Receiver in the same Node it WORKS but when I have them in different Nodes it does NOT WORK.
What is it that I am missing here??
By calling setInterface() to the local host you are preventing the joinGroup() message from leaving the current host. That doesn't matter in the sender, because a sender doesn't have to join the group anyway, but in the receiver it will prevent other hosts, routers, etc. from knowing that the receiving host is in the group.
Just remove it.
I am a student on holiday and I decided to make a server application for fun. So the problem is: My class - Server.java - is a server created with ServerSocket, but when I try to construct a Thread class - ServerThread.java - something I have never seen before happens. I debugged the class and when I step into the constructor of ServerThread called in Server.java, it doesn't go into ServerThread but instead goes into ClassLoader.class. I assume this normally also happens at some point, but now only this gets called and not the constructor of ServerThread.
I have been struggling with this for the past 3 days, almost non-stop, but for the love of Pete I cannot get it to work.
Here is my Server.java code:
public class Server
{
private ArrayList<Socket> sockets;
private ServerSocket ss;
// Constructor and while-accept loop all in one.
public Server( int port ) throws IOException
{
Runtime.getRuntime().addShutdownHook(new Thread()
{
#Override
public void run()
{
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
// All we have to do is listen
listen( port );
}
// Main routine
// Usage: java Server >port<
static public void main( String args[] ) throws Exception
{
// Get the port # from the command line
int port = 5003;
// Create a Server object, which will automatically begin
// accepting connections.
new Server( port );
}
private void listen( int port ) throws IOException
{
// Create the ServerSocket
ss = new ServerSocket(port, 0, InetAddress.getByName("10.0.0.6"));
// Tell the world we're ready to go
System.out.println( "Listening on " + ss );
sockets = new ArrayList<Socket>();
// Keep accepting connections forever
while (true)
{
// Grab the next incoming connection
Socket s = ss.accept();
// Tell the world we've got it
System.out.println( "Connection from " + s );
sockets.add(s);
// Create a new thread for this connection, and then forget
// about it
new ServerThread( this, s );
}
}
public void removeConnection(Socket socket) throws IOException
{
synchronized (sockets)
{
sockets.remove(socket);
System.out.println("Closing connection at " + socket);
socket.close();
}
}
public void sendToAll(Socket s, String msg) throws IOException
{
synchronized (sockets)
{
for (int i = 0; i < sockets.size(); i++)
{
if (!sockets.get(i).equals(s))
{
new BufferedWriter(new OutputStreamWriter(sockets.get(i).getOutputStream())).write(msg);
}
}
}
}
}
And here is my ServerThread.java code:
public class ServerThread extends Thread
{
private Server server;
private Socket socket;
public ServerThread( Server server, Socket socket )
{
// Save the parameters
this.server = server;
this.socket = socket;
// Start up the thread
start();
}
// This runs in a separate thread when start() is called in the
// constructor.
public void run()
{
try
{
// Create a DataInputStream for communication; the client
// is using a DataOutputStream to write to us
BufferedReader din = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// Over and over, forever ...
while (true)
{
String message = "";
try
{
// ... read the next message ...
message = din.readLine();
// ... tell the world ...
System.out.println( "Sending "+message );
server.sendToAll(socket, message);
}
catch (SocketException ex)
{
break;
}
System.out.println("GG");
}
}
catch( EOFException ie )
{
ie.printStackTrace();
System.out.println("GG1");
}
catch( IOException ie )
{
// This does; tell the world!
ie.printStackTrace();
System.out.println("GG2");
}
finally
{
// The connection is closed for one reason or another,
// so have the server dealing with it
try {
server.removeConnection( socket );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I hope I have made myself clear enough...
If you are debugging step-by-step and you reach a new expression that requires a currently unloaded class, you will step in to the class loader.
This is normal behavior. You will have to step out, possibly multiple times, to get back to your code.
Ok. It turns out the constructor was called but the program hanged at din.readLine(). I coudn't figure out why that happened because I did add a '\n' character at the end of the message, so I instead changed the BufferedReader and BufferedWriter objects to java.io.DataInputStream and java.io.DataOutputStream and used the readUTF() and writeUTF() methods, and this worked. Thank you for everyone's answers and time :).