Java DatagramSocket doesn't receive data - java

I'm writing a simple client / server in java and I got this problem that I cannot fix.
I'm using DatagramSocket on both client and server and my server just cannot receive any data. I don't get any errors but it just doesn't work.
Here is my source code for server:
public class GameServer {
public static final String serverBuild = "0.00 (050319.milestone0-main)";
public static final String protocolBuild = "1";
public DatagramSocket serverSocket;
public boolean isRunning = false;
public Thread clientHandler;
public GameServer(int port, String serverName) {
System.out.println("Server> Starting a server on port: " + port + ".");
System.out.println("Server> " + serverName + " running on server build " + serverBuild + ".");
System.out.println("Server> Using protocol ID: " + protocolBuild + ".");
isRunning = true;
try {
serverSocket = new DatagramSocket(port);
}catch(Exception ex) {
System.out.print("Server> ");
ex.printStackTrace();
}
clientHandler();
}
public void clientHandler() {
clientHandler = new Thread(new Runnable() {
public void run() {
while(isRunning) {
byte[] buffer = new byte[256];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
try {
serverSocket.receive(packet);
System.out.println("Server> " + new String(packet.getData(), 0, packet.getData().length));
} catch (IOException e) {
System.out.print("Server> ");
e.printStackTrace();
}
}
}
});
clientHandler.start();
}
}
Here is my source code for client:
public class GameClient {
public GameClient() {
try {
DatagramSocket socket = new DatagramSocket(25567);
byte[] buffer = new byte[256];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("192.168.0.24"), 25567);
socket.send(packet);
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
Client is very simple because I was looking why my server doesn't work.

The console does not print anything, because the client sends the package is an empty array. The server is work right.

Related

How to group 2 udp clients?

What i'm trying to do is group 2 clients and make them communicate with eachother. So if 2 clients are connected they would only be able to communicate with eachother and if a third client got connected it would not be able to communicate with the 2 other clients but it would create another group of 2 clients and so on... Right now if a client sends a message it send it over to all clients but i don't know how to make it work like described above. Messages are send from client by typing something in console.
server:
public class Server extends Thread{
public final static int PORT = 7331;
private final static int BUFFER = 1024;
private DatagramSocket socket;
private ArrayList<InetAddress> clientAddresses;
private ArrayList<Integer> clientPorts;
private HashSet<String> existingClients;
public Server() throws IOException {
socket = new DatagramSocket(PORT);
System.out.println("[SERVER] UDP server successfully launched on port " + PORT);
clientAddresses = new ArrayList<InetAddress>();
clientPorts = new ArrayList<Integer>();
existingClients = new HashSet<String>();
}
public void run() {
byte[] buf = new byte[BUFFER];
while (true) {
try {
//resets buffer so only new messages get displayed
Arrays.fill(buf, (byte) 0);
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String content = new String(buf, buf.length);
InetAddress clientAddress = packet.getAddress();
int clientPort = packet.getPort();
String id = clientAddress.toString() + "," + clientPort;
if (!existingClients.contains(id)) {
existingClients.add(id);
clientPorts.add(clientPort);
clientAddresses.add(clientAddress);
}
System.out.println(id + " : " + content);
byte[] data = (id + " : " + content).getBytes();
for (int i = 0; i < clientAddresses.size(); i++) {
InetAddress cl = clientAddresses.get(i);
int cp = clientPorts.get(i);
packet = new DatagramPacket(data, data.length, cl, cp);
socket.send(packet);
}
} catch (Exception e) {
System.err.println(e);
}
}
}
public static void main(String args[]) throws Exception {
Server s = new Server();
s.start();
}
}
clients:
public class Client implements Runnable {
public static void main(String args[]) throws Exception {
String host = "127.0.0.1";
DatagramSocket socket = new DatagramSocket();
//handles the receiving part for every client (incoming packets to clients)
MessageReceiver r = new MessageReceiver(socket);
Client s = new Client(socket, host);
Thread rt = new Thread(r);
Thread st = new Thread(s);
rt.start();
st.start();
}
public final static int PORT = 7331;
private DatagramSocket sock;
private String hostname;
Client(DatagramSocket s, String h) {
sock = s;
hostname = h;
}
//sending clients socket to server
private void sendMessage(String s) throws Exception {
//getting bytes from message
byte buf[] = s.getBytes();
//getting hostname from server
InetAddress address = InetAddress.getByName(hostname);
//setting up packet
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, PORT);
//sending packet to server
sock.send(packet);
}
public void run() {
//connected boolean is used to send a greetings message once for every new client that has joined
boolean connected = false;
do {
try {
sendMessage("GREETINGS");
connected = true;
} catch (Exception e) {
}
} while (!connected);
//reads from the console
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (true) {
try {
while (!in.ready()) {
Thread.sleep(100);
}
//sends message from console to server
sendMessage(in.readLine());
} catch (Exception e) {
System.err.println(e);
}
}
}
}
//this class handles receiving part of clients
class MessageReceiver implements Runnable {
DatagramSocket sock;
byte buf[];
MessageReceiver(DatagramSocket s) {
sock = s;
buf = new byte[1024];
}
public void run() {
while (true) {
try {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
sock.receive(packet);
String received = new String(packet.getData(), 0,
packet.getLength());
System.out.println(received);
} catch (Exception e) {
System.err.println(e);
}
}
}
}
What youre trying is a message broadcast or a message-repeater-client.
broadcasting is implemented on network layer (using brodcast the local network broadcast adress).
And if you implementing it that way, you'll flood your network, when you have more than 2 clients. Best regards to your network admin. ;-)

Get string size from Datagram Packet

I'm new to programming and I'm studying sockets, maybe this question is stupid, but thank you for your help.
I'm trying to extract the size of a message sent to the server(number of characters), but the size of the message sent in the server response always has a different size.
Client
import java.net.*;
import java.io.*;
public class UDPClient {
public static void main(String args[]) {
// args give message contents and server hostname
if (args.length != 2) {
System.err.println("Usage: java UDPClient 'Text Message' <server hostname>");
System.exit(1);
}
DatagramSocket aSocket = null;
try {
aSocket = new DatagramSocket();
byte[] m = args[0].getBytes();
InetAddress aHost = InetAddress.getByName(args[1]);
int serverPort = 6789;
DatagramPacket request = new DatagramPacket(m, m.length, aHost, serverPort);
aSocket.send(request);
byte[] buffer = new byte[1000];
DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
aSocket.receive(reply);
System.out.println("Reply: " + new String(reply.getData()));
System.out.println("Reply: " + reply.getData().toString().length());
} catch (SocketException e) {
System.out.println("Socket: " + e.getMessage());
} catch (IOException e) {
System.out.println("IO: " + e.getMessage());
} finally {
if (aSocket != null)
aSocket.close();
}
}
}
Server
import java.net.*;
import java.io.*;
public class UDPServer {
public static void main(String args[]) {
DatagramSocket aSocket = null;
try {
aSocket = new DatagramSocket(6789);
byte[] buffer = new byte[1000];
while (true) {
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
aSocket.receive(request);
String m = new String(request.getData()).replaceAll(" ", "");
int tam = m.length();
DatagramPacket reply = new DatagramPacket(request.getData(), tam, request.getAddress(),
request.getPort());
aSocket.send(reply);
}
} catch (SocketException e) {
System.out.println("Socket: " + e.getMessage());
} catch (IOException e) {
System.out.println("IO: " + e.getMessage());
} finally {
if (aSocket != null)
aSocket.close();
}
}
}

Java SocketServer Connected to a AccessGuard 1000 Solution

I have the following issue connecting to a AccessGard (newnet) solution that forwards TPC messages to my application from a POS.
Basically the AG automatically connects from an ip "X.X.X.2" to my pooled server but it never sends any data.
When the POS send the message for some reason the AG sends the TPC request from another IP "X.X.X.132" but it never triggers the serverSocket.accept()
With wiresharck I can see Keep Alive messages from the X.X.X.2 to my server every second. Also I can see the request incoming from ip "X.X.X.132" but it never reaches the server. All the incoming transmissions come to the same port.
here is my server :
public class Server2 {
protected int serverPort = 8005;
protected ServerSocket serverSocket = null;
protected boolean isStopped = false;
protected Thread runningThread= null;
protected ExecutorService threadPool = Executors.newFixedThreadPool(10);
public Server2()
{}
public void run(){
openServerSocket();
while(! isStopped()){
Socket clientSocket = null;
try {
clientSocket = this.serverSocket.accept();
} catch (IOException e) {
if(isStopped()) {
System.out.println("Server Stopped.") ;
break;
}
throw new RuntimeException(
"Error accepting client connection", e);
}
this.threadPool.execute(
new WorkerRunnable(clientSocket,
"Thread Pooled Server"));
}
this.threadPool.shutdown();
System.out.println("Server Stopped.") ;
}
private void openServerSocket() {
try {
this.serverSocket = new ServerSocket(this.serverPort);
} catch (IOException e) {
throw new RuntimeException("Cannot open port 8005", e);
}
}
private synchronized boolean isStopped() {
return this.isStopped;
}
}
here the worker:
public class WorkerRunnable implements Runnable
{
private static final Logger logger = Logger.getLogger(WorkerRunnable.class);
protected Socket connectionSocket = null;
protected String serverText = null;
public WorkerRunnable(Socket connectionSocket, String serverText) {
this.connectionSocket = connectionSocket;
this.serverText = serverText;
}
public void run() {
try {
System.out.println(read());
} catch (IOException e) {
//report exception somewhere.
e.printStackTrace();
}
}
private String read() throws IOException
{
InputStream in = connectionSocket.getInputStream();
byte[] m = new byte[2];
in.read(m,0,2);
ByteBuffer wrapped = ByteBuffer.wrap(m);
short num = wrapped.getShort();
logger.info("IN message length:" + num +" Hexa:" + String.format("%02x", m[0]) + String.format("%02x", m[1])); System.out.println("IN message length:" + num +" Hexa:" + String.format("%02x", m[0]) + String.format("%02x", m[1]));
byte[] message = new byte[num];
in.read(message,0,num);
String inMessage = Util.bytesToHex(message);
logger.info("Full message:" + inMessage); System.out.println("Full message:" + inMessage );
return inMessage;
}
}

TCP server madness - Slow and Merged data

I recently started to make a 2d java game, now I began the TCP server, though the server runs insanely slow (Average of 2 seconds) and I can't figure out how to stop the input stream from metering all the data into one string. I would greatly appreciate it if someone is able to help me.
ServerCode:
package com.diedericksclan.main.network;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class ServerThread extends Thread {
private ServerHandler server;
private ServerSocket dataSocket;
private Socket socket;
private InetSocketAddress address;
private int megabyte = 1024 * 1024;
private int dedicated = 1024;
public int RAM = megabyte * dedicated;
private WriteData send;
private ReadData read;
public ServerThread(ServerHandler server, String serverIP, int ram, int backlog) throws Exception {
this.server = server;
this.dedicated = ram;
//System.out.println(serverIP);
String ip = "localhost";
int port = 2048;
if(serverIP.contains(":")) {
ip = serverIP.split(":")[0];
port = Integer.parseInt(serverIP.split(":")[1]);
} else {
ip = serverIP;
port = 2048;
}
//System.out.println("Makin' the server");
this.dataSocket = new ServerSocket(port, backlog, InetAddress.getByName(ip));
this.address = new InetSocketAddress(dataSocket.getInetAddress(), port);
this.send = new WriteData();
this.read = new ReadData();
//System.out.println("Makin' the data handlers");
//System.out.println("Server has been made, details: " + address.getAddress() + ":" + address.getPort());
}
public ServerThread(ServerHandler server, String ip) throws Exception {
this(server, ip, 1024, 0);
}
public void run() {
//System.out.println("made");
this.send.start();
this.read.start();
while(true) {
try {
socket = dataSocket.accept();
socket.setReceiveBufferSize(megabyte);
socket.setSendBufferSize(megabyte);
socket.setTcpNoDelay(true);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void sendData(byte[] data, InetAddress IPaddress, int port) {
this.send.sendData(data, IPaddress, port);
}
public void serverShutdown() {
try {
this.dataSocket.close();
if(this.socket != null) this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public class WriteData extends Thread {
public WriteData() {}
public void sendData(byte[] data, InetAddress IPaddress, int port) {
try {
System.out.println("[" + System.currentTimeMillis() + "] Sending... " + new String(data));
socket.getOutputStream().write(data);
socket.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ReadData extends Thread {
public ReadData() {}
public void run() {
try {
this.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
byte[] data;
while(true) {
try {
data = new byte[megabyte];
socket.getInputStream().read(data);
System.out.println("[" + System.currentTimeMillis() + "] Server has read, " + new String(data) + ", details: " + socket.getLocalAddress().getHostName() + ":" + socket.getLocalPort());
server.parsePacket(data, socket.getInetAddress(), socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
ClientCode:
package com.diedericksclan.main.network;
import java.io.*;
import java.net.*;
public class ClientThread extends Thread {
private ClientHandler client;
private Socket socket;
private InetSocketAddress address;
private int megabyte = 1024 * 1024;
private WriteData send;
private ReadData read;
public ClientThread(ClientHandler client) {
this.client = client;
this.address = new InetSocketAddress("192.168.1.2", 2048);
socket = new Socket();
try {
socket.setSendBufferSize(megabyte);
socket.setSendBufferSize(megabyte);
socket.setTcpNoDelay(true);
socket.connect(address);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//System.out.println("Made client");
this.send = new WriteData();
this.read = new ReadData();
//System.out.println("Client has been made, details: " + socket.getLocalAddress() + ":" + socket.getLocalPort());
}
public void run() {
//System.out.println("made");
this.send.start();
this.read.start();
}
public void sendData(byte[] data) {
this.send.sendData(data);
}
public void serverShutdown() {
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public class WriteData extends Thread {
public WriteData() {}
public void sendData(byte[] data) {
try {
//System.out.println("[" + System.currentTimeMillis() + "] Sending... " + new String(data) + " to: " + socket.getInetAddress() + ":" + socket.getPort());
socket.getOutputStream().write(data);
socket.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ReadData extends Thread {
public ReadData() {}
public void run() {
byte[] data;
while(true) {
try {
data = new byte[megabyte];
socket.getInputStream().read(data);
System.out.println("[" + System.currentTimeMillis() + "] Server data recived, " + new String(data).trim());
client.parsePacket(data, socket.getInetAddress(), socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I did try to improve speed by making 2 separate threads for reading and writing data, in both the client and server, yet there was no improvement,
You have a few problems.
you allow any number of threads to write to the same socket at the same time. This makes developing a protocol very hard.
you need a protocol so you know where a message starts and end. e.g. you send the length first.
you ignore how many bytes where read. The minimum will be 1 and you can get any number of messages up to the size of the buffer at once. TCP is a stream protocol, not a messaging protocol.
If you have a reader and writer process on the same machine you should be able to get the latency to around 10 micro-seconds. (0.000010 seconds)
EDIT here is a simple example
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class PlainIOSample {
static final int RUNS = 1000000;
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(0);
DataSocket ds = new DataSocket(new Socket("localhost", ss.getLocalPort()));
DataSocket ds2 = new DataSocket(ss.accept());
long start = System.nanoTime();
for (int i = 0; i < RUNS; i++) {
// send a small message
ds.write(new byte[64]);
// receive the same message
byte[] bytes = ds2.read();
if (bytes.length != 64)
throw new AssertionError();
}
long time = System.nanoTime() - start;
System.out.printf("Average time to send/recv was %.1f micro-seconds%n",
time / RUNS / 1e3);
ds.close();
ds2.close();
}
static class DataSocket implements Closeable {
private final DataOutputStream dos;
private final DataInputStream dis;
private final Socket socket;
public DataSocket(Socket socket) throws IOException {
dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
this.socket = socket;
}
public void write(byte[] message) throws IOException {
synchronized (dos) {
dos.writeInt(message.length);
dos.write(message);
dos.flush();
}
}
public byte[] read() throws IOException {
synchronized (dis) {
int length = dis.readInt();
byte[] bytes = new byte[length];
dis.readFully(bytes);
return bytes;
}
}
#Override
public void close() throws IOException {
socket.close();
}
}
}
prints
Average time to send/recv was 3.3 micro-seconds

Why are my sockets only able to communicate client-to-server and not server-to-client?

I have written a simple Java dispatcher with a daemon thread to handle the incoming traffic, and using another thread to send out commands.
The problem comes when the server receives the first message, then the client/server system gets stuck on where the server trying to send out a response to the client. The sockets on both end just simply freeze when the server sends out data.
I have simplified my original problem into a echo server and client; I guess I must have a very very stupid mistake on the code. The code and result on my machine are reproduced below. Can anyone explain what is going wrong?
Thanks!
Here is the results, we can see the server and client stuck once the first message received.
Echo Server listening port...
Echo Server: Waiting from client connection.
Connecting to the server.
Connected to the server.
Dispatcher send: 10
Dispatcher send: 11
Dispatcher send: 12
Dispatcher send: 13
Dispatcher read...
Dispatcher read...
Dispatcher readed 10
Code:
EchoTest:
import java.io.*;
import java.net.*;
public class EchoTest {
public static void main(String[] args) {
EchoServer.listen();
EchoClient client = new EchoClient();
EchoServer server = EchoServer.accept();
}
}
Client and Server:
class EchoClient implements Runnable {
private static final int PORT = 13244;
Socket socket;
Disp disp;
Thread client;
public EchoClient() {
client = new Thread(this);
client.start();
}
public void run() {
try {
System.out.println("Connecting to the server.");
Socket socket = new Socket("localhost", PORT);
System.out.println("Connected to the server.");
disp = new Disp(socket);
disp.send(10);
disp.send(11);
disp.send(12);
disp.send(13);
} catch(IOException e) {
System.out.println("Would not connect to local host: " + PORT);
System.exit(-1);
}
}
public void send(int m) {
disp.send(m);
System.out.println("Sent message " + m);
int echo = disp.getMsg();
if(m == echo) {
System.out.println("Message " + m + "sent and received.");
} else {
System.out.println("Message " + m + "cannot be echoed correctly.");
}
}
}
class EchoServer implements Runnable{
private static final int PORT = 13244;
private static ServerSocket serverSocket;
Disp disp;
public EchoServer(Socket s) {
disp = new Disp(s);
}
public static void listen() {
System.out.println("Echo Server listening port...");
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
System.out.println("Could not listen on port: " + PORT);
System.exit(-1);
}
}
public static EchoServer accept(){
try {
System.out.println("Echo Server: Waiting from client connection.");
return new EchoServer(serverSocket.accept());
} catch(IOException e) {
System.out.println("Couldn't accept connection from client.");
System.exit(-1);
}
return null;
}
public void run() {
while(true) {
int m = disp.getMsg();
disp.send(m);
}
}
}
Disp:
class Disp implements Runnable{
int msg = -1;
Socket socket;
BufferedInputStream input;
DataInputStream dis;
BufferedOutputStream output;
DataOutputStream dos;
Thread daemon;
public Disp(Socket s) {
this.socket = s;
try{
input = new BufferedInputStream(socket.getInputStream());
dis = new DataInputStream(input);
output = new BufferedOutputStream(socket.getOutputStream());
dos = new DataOutputStream(output);
}catch(IOException e) {
}
daemon = new Thread(this);
daemon.start();
}
public void run() {
while(true) {
int m = get();
setMsg(m);
}
}
public void send(int m) {
synchronized(dos) {
try{
System.out.println("Dispatcher send: " + m);
dos.writeInt(m);
dos.flush();
} catch(IOException e) {
}
}
}
public int get() {
System.out.println("Dispatcher read...");
synchronized(dis) {
try{
int m = dis.readInt();
System.out.println("Dispatcher readed " + m);
return m;
} catch(IOException e) {
}
}
return -1;
}
synchronized public void setMsg(int m) {
while(true) {
if(msg == -1) {
try {
wait();
} catch(InterruptedException e) {
}
} else {
msg = m;
notifyAll();
}
}
}
synchronized public int getMsg() {
while(true) {
if(msg != -1) {
try {
wait();
} catch(InterruptedException e) {
}
} else {
notifyAll();
return msg;
}
}
}
}
That's an awful lot of code. First of all I suggest cutting it down.
Secondly, you never seem to call EchoServer.run, but it's difficult to see.
You should also set the TCP_NODELAY flag, as you send only a few bytes. The Operating system usually waits for more data before it sends a package (and your flush() has no influence over that behaviour, as flush only deals with java's buffers).

Categories