This is about Java 'network' library

It’s about JAVA ‘network’ library.

Hello. Nice to meet you.

import processing.net.*;

int port = 10002;
Server myServer;

void setup()
{
size(400, 400);
background(0);
myServer = new Server(this, port); // Starts a server on port 10002
}

void draw() {

}

void serverEvent(Server someServer, Client someClient) {

someClient.ip();
someClient.readString(); // -?

}

This is about JAVA ‘network’ library.

Hello. Nice to meet you.

  1. Please look at the source code.
  2. ‘serverEvent’ processes immediately when a ‘client’ event occurs.
    The problem is that I want to see the client’s packet data, but I can’t.

Is there a solution?

  • The serverEvent triggers when a client connects, not necessarily when data arrives
  • For continuous data streams, you might want to move the reading logic to draw()
1 Like

Something like this could help

void serverEvent(Server server, Client client) {
  
  println("New client connected: " + client.ip() + ":" + client.port());
  
  
  while (client.available() > 0) {
    // Option 1: Read as string (for text protocols)
    String msg = client.readString();
    if (msg != null) {
      println("Received string data: " + msg.trim());
    }
    
    // Option 2: Read as bytes (for binary data)
    byte[] data = client.readBytes();
    if (data != null) {
      println("Received binary data (" + data.length + " bytes):");
      printPacketData(data);
    }
  }
}

void printPacketData(byte[] data) {
  // Print hex dump
  print("Hex: ");
  for (byte b : data) {
    print(hex(b, 2) + " ");
  }
  println();
  
  // Print ASCII interpretation
  print("ASCII: ");
  for (byte b : data) {
    if (b >= 32 && b <= 126) { // Printable ASCII range
      print(char(b));
    } else {
      print('.'); // Show non-printable as dots
    }
  }
  println();
}

1 Like

@jafal

Thanks for the reply.

I’ll try it.

Thank you

1 Like

Hello @GWAK ,

Working example below that will receive data in the server sketch.

Server and client (start first)

// Server and client

import processing.net.*;

Server server0;
Client client0;

void setup() 
  {
  size(400, 200);
  server0 = new Server(this, 5204);  // Listen on port 5204
  println("Server started on port 5204");
  }

void draw() 
  {
  }

void serverEvent(Server server, Client client) 
  {
  println("New client connected: " + client.ip());
  server.write("Start sending...");
  }
  
void clientEvent(Client myClient) 
  {
  print("Client0 received:  ");
  String dataIn = myClient.readString();
  println(dataIn);
  }  

Client (start second)

// Client

import processing.net.*;

Client client1;
boolean sendData = false;

int count = 0;

void setup() 
  {
  size(200, 200);
  client1 = new Client(this, "127.0.0.1", 5204);
  }

void draw() 
  { 
  // Sends data every 60 frames
  if (sendData)
    {
    if (frameCount%60 == 0) // Every 1 sec at if frameRate = 60
      {
      println("Client1 sending: " + count);
      client1.write(str(count)); // Sends data to server
      count++;
      }
    }
  }

// Once the client connects to server it starts sending data
void clientEvent(Client myClient) 
  {
  print("Server Says:  ");
  String dataIn = myClient.readString();
  println(dataIn);
  
  if(dataIn.equals("Start sending..."))
    sendData = true;
  }

I used the console to show messages and data sent and received.
You will have to make each sketch active (click with mouse) to see updates (sending and receiving) in console.

You could also receive the data in draw():

// Server and client

import processing.net.*;

Server server0;
Client client0;

void setup() 
  {
  server0 = new Server(this, 5204);  // Listen on port 5204
  println("Server started on port 5204");
  }

void draw() 
  {
  // Get the next available client
  client0 = server0.available();
  
  if (client0 != null) 
    {
    println("Client connected: " + client0.ip());
        
    while (client0.available() > 0) 
      {
      // Read the data sent by the client1
      String msg = client0.readString(); 
        {
        println("Received: " + msg);
        }
      }
    }    
  }

void serverEvent(Server server, Client client) 
  {
  println("New client connected: " + client.ip());
  server.write("Start sending...");
  }
  
//void clientEvent(Client myClient) 
//  {
//  print("Client0 received:  ");
//  String dataIn = myClient.readString();
//  println(dataIn);
//  }  

I got a lot of insight from here:

Reference:

And the examples that come with Processing for the Network library.

And a lot of testing and troubleshooting!

Have fun!

:)

2 Likes

Hello @GWAK ,

Did you have any success with that code snippet? If so please share.

  • I was not able to receive data within serverEvent() with example code.

  • client.port() is not available for the processing.net library and gives this error:
    The function port() does not exist.

Hello @jafal ,

Do you have a complete working example (server and client code) including that code snippet?
Please post this.
I’m interested in seeing this because I couldn’t get it to work.

:)

1 Like

Hello @jafal,

I did manage to get your code snippet to work integrated with my working example and some adjustments.

I had to add a delay() so that the client data that was sent was buffered and would be available after the connection to receive it.
I also removed client.port() as it is not available in the network library.
It only received data while it was available… 19 elements buffered.

With delay(20000) and sending data every 1 sec there were 20 elements in the buffer to receive and then it exited from the serverEvent() and stop receiving data that continued to be sent by the client.

The hex and ASCII display was a nice touch!

:)

2 Likes

@glv
@jafal

I found a practical usage.

  1. It can be operated through threads.
  2. It can accept multiple users.
  3. It was processed using ‘serverEvent’.

It works pretty well, thank you.

import processing.net.*;
import java.util.concurrent.CopyOnWriteArrayList;

Server server;
CopyOnWriteArrayList<Client> clients = new CopyOnWriteArrayList<Client>();

void setup() {
  size(400, 400);
  server = new Server(this, 5204);
  println("서버 시작됨 (포트 5204)");

  Thread serverThread = new Thread(new Runnable() {
    public void run() {
      handleClients();
    }
  });
  serverThread.start();
}

void draw() {
  background(200);
  text("클라이언트 수: " + clients.size(), 20, 30);
}

// 새로운 클라이언트가 접속되었을 때 호출
void serverEvent(Server someServer, Client newClient) {
  println("접속됨: " + newClient.ip());
  clients.add(newClient);
}

// 비동기 메시지 수신 + 응답 + 연결 종료 처리
void handleClients() {
  while (true) {
    for (Client c : clients) {
      if (!c.active()) {
        println("클라이언트 연결 해제됨: " + c.ip());
        clients.remove(c);
        continue;
      }

      if (c.available() > 0) {
        String msg = c.readStringUntil('\n');
        if (msg != null) {
          msg = msg.trim();
          println("[" + c.ip() + "] 받은 메시지: " + msg);

          // 1) 답문 (예: Echo)
          String reply = "서버 응답: " + msg + "\n";
          c.write(reply);
          println("[" + c.ip() + "] 답문 전송 완료");

          // 2) 특정 키워드가 오면 통신 끊기
          if (msg.equalsIgnoreCase("bye")) {
            println("[" + c.ip() + "] 연결 종료됨 (bye 명령)");
            c.stop();       // 연결 종료
            clients.remove(c);  // 리스트에서 제거
          }
        }
      }
    }
    delay(10);
  }
}
2 Likes

You are a very smart and talented person. If you find the right opportunity, you will be creative.

1 Like

Nice work
Mark your post as solved

1 Like

Hello @GWAK,

Cool! I asked an AI to translate (it also commented) to English and tested and it works!

I am always interested in the process for finding solutions and\or the source of code.

What was the development process for finding this solution, source of code or inspiration for this?

For me, development typically involves a combination of reading, research, hands-on experience, working with large language models like ChatGPT and OpenGemini, and continuous testing.

Lately, I’ve been using LLMs more frequently and had an interesting experience engaging in a step-by-step dialogue where I had to correct the model multiple times and often receiving apologies in return. Many of the suggested solutions didn’t work initially, so it became a very iterative process. At one point, I even had to ‘educate’ the model by providing Processing source code and links to relevant references. It thanked me but then forgot later! :slight_smile: In the end it did provide some insight and added value to the discussion. It is useful as long as you have experience and scrutinize the solutions offered.

Thanks in advance.

:)

1 Like

Let’s work together to help each other.

Thank you.

@jafal @glv

2 Likes

Hi @GWAK ,

Your topic certainly engaged me! And then I start exploring to learn more…

I took interest in the usage of thread in your example and also replaced it with the simple Processing thread() helper function and it worked :

  //Thread serverThread = new Thread(new Runnable() 
  //  {
  //  public void run() 
  //    {
  //    // Call the method to handle connected clients
  //    handleClients();
  //    }
  //  });
  //// Start the server thread
  //serverThread.start();
  
 // Processing thread
  thread("handleClients");
  }

I looked this up in the Processing source and it is similar to what you coded directly:

Reference:
thread() / Reference / Processing.org

Cool beans!

:)

1 Like

Simple client

import java.net.*;
import java.io.*;

Socket socket;
PrintWriter out;
BufferedReader in;

String serverIP = "192.168.1.100"; // Change to server IP
int port = 5204;
String messageToSend = "Hello from client!";
String response = "Not connected";

void setup() {
  size(400, 200);
  textAlign(CENTER, CENTER);
  
  // Connect in a separate thread
  new Thread(new Runnable() {
    public void run() {
      try {
        socket = new Socket(serverIP, port);
        out = new PrintWriter(socket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        
        out.println(messageToSend);
        response = in.readLine();
        println("Server response: " + response);
      } 
      catch (IOException e) {
        response = "Connection failed: " + e.getMessage();
        e.printStackTrace();
      }
    }
  }).start();
}

void draw() {
  background(0);
  fill(255);
  text("Client\nSent: " + messageToSend + "\nResponse: " + response, width/2, height/2);
}

void exit() {
  try {
    if (in != null) in.close();
    if (out != null) out.close();
    if (socket != null) socket.close();
  } 
  catch (IOException e) {
    e.printStackTrace();
  }
  //super.exit();
}

2 Likes

Hello folks,

This is more for the general community to add to the topic.

I was able to connect these two and communicate between them:

  // Counter using frameCount:
  if(frameCount%60 == 0)
    {
    int counter = frameCount/60;  
    out.println(counter);
    println("Sent to server: " + counter);
    }

If you are running this code on a single PC try this with 2 different sketches for client with 2 different IPs:

  • Client Sketch 1
    String serverIP = “192.168.213.1”; // Server IP of PC (This is my PC and will change on your computer).

  • Client Sketch 2
    String serverIP = “127.0.0.1”; // Server IP using localHost

Connecting these two clients to the server (with some delay) I was able to see the two connections and data received in Server console:

How cool is that!

There are different libraries used and some advanced topics.
Some research will provide clarity.

I found ChatGPT and Gemini useful for:

  • Commenting\explaining code.
  • It also made suggestions for consideration.
  • Converting code from Processing only library to Java library and vice versa.
  • Keep in mind that all ChatGPT code and responses should be scrutinized!
    It may be incorrect and very apologetic for it. It is doing unsupervised training and self learning along the way and sometimes has incorrect answers.

Thanks @GWAK and @jafal for code provided.
The code provided looks like a solid implementation using familiar and widely adopted components and code which was adapted for the Processing environment.
It took a lot research on my part to sift through all the code and thoroughly understand the implementation.

It is important to provide context with code that is shared:
Guidelines—Answering Questions
Comments and references are important to provide context; I will have to discipline myself to do that and posted this to help others with the code provided. I sometimes look at my older code and have no idea what I was doing from lack of comments or references! :slight_smile:

I certainly enjoyed the exploration of this but it may be a challenge for others.

Have fun! I learned a lot!

:)

2 Likes