Why can't I send packets between client and server using UDP - java

I have a problem with communication between client and server using UDP protocol in Java. I made Client and Server classes and two classes SingleCom responsible for sending and receiving packets.
I tried to test the connection (I run client on one computer and server on another; both create DatagramSocket on the same port) simply by sending "START" string from client to server and after that server should print the string on the console and send back "ACCEPTED", but either client nor server print anything on its console. Could anyone tell me what is going on and why?
Below I show simplified classes (I separated server and client in other packets):
//Client:
public class Client
{
protected static InetAddress serverAddress;
protected static InetAddress clientAdr;
protected static int port;
protected static SingleCom connection;
public static final int PACKET_SIZE = 1024;
public static void main(String[] args) throws IOException, InterruptedException
{
//get server address and port typed from console
load();
connection = new SingleCom();
connection.initilize();
Thread privcastTread = new Thread(connection);
privcastTread.start();
//sending the simplest packet
connection.sendPacket("START", serverAddress);
}
public static synchronized void handlePacket(DatagramPacket packet, String msg) throws IOException
{
if (msg.startsWith("ACCEPTED"))
{
System.out.println("Accepted");
}
}
}
//SingleCom for Client
public class SingleCom implements Runnable
{
DatagramSocket udpSocket;
#Override
public void run()
{
try
{
byte[] buffer = new byte[8192];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while(true)
{
udpSocket.receive(packet);
String msg = new String(buffer, 0, packet.getLength());
Client.handlePacket(packet, msg);
packet.setLength(buffer.length);
}
}
catch (SocketException e)
{
System.exit(1);
}
catch (IOException e)
{
System.exit(1);
}
}
public void initilize() throws IOException
{
udpSocket = new DatagramSocket(Client.port, InetAddress.getLocalHost());
}
public void sendPacket(String text, InetAddress target) throws IOException
{
byte[] sendedMsg = text.getBytes();
DatagramPacket sendedPacket = new DatagramPacket(sendedMsg, sendedMsg.length, target, Client.port);
udpSocket.send(sendedPacket);
}
public void sendPacket(String text) throws IOException
{
sendPacket(text, Client.serverAddress)
}
public void sendPacket(byte[] content) throws IOException
{
//byte[] sendedMsg = text.getBytes();
DatagramPacket sendedPacket = new DatagramPacket(content, content.length, Client.serverAddress, Client.port);
udpSocket.send(sendedPacket);
}
}
//Server
public class Server
{
protected static InetAddress serverAdr;
protected static InetAddress clientAdr;
protected static SingleCom connection;
protected static int port;
protected static int speed; //in KB/s
private static FileOutputStream fos;
public static void main(String[] args) throws IOException
{
load();
connection = new SingleCom();
connection.initilize();
Thread privcastTread = new Thread(connection);
privcastTread.start();
}
public static synchronized void handlePacket(DatagramPacket pakiet, String msg) throws IOException
{
String[] pieces;
if (msg.startsWith("START"))
{
System.out.println(pieces[0]);
connection.sendPacket("ACCEPTED", clientAdr);
}
}
}
//connection for Server
public class ServerCom implements Runnable
{
DatagramSocket udpSocket;
#Override
public void run()
{
try
{
byte[] buffer = new byte[8192];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while(true)
{
udpSocket.receive(packet);
String msg = new String(buffer, 0, packet.getLength());
Server.handlePacket(packet, msg);
packet.setLength(buffer.length);
}
}
catch (SocketException e)
{
System.exit(1);
}
catch (IOException e)
{
System.exit(1);
}
}
public void initilize() throws IOException
{
udpSocket = new DatagramSocket(Server.port, InetAddress.getLocalHost());
}
public void sendPacket(String text, InetAddress target) throws IOException
{
byte[] sendedMsg = text.getBytes();
DatagramPacket sendedPacket = new DatagramPacket(sendedMsg, sendedMsg.length, target, Server.port);
udpSocket.send(sendedPacket);
}
public void sendPacket(String text) throws IOException
{
sendPacket(text, Server.clientAdr);
}
}

Related

How to send messages between two 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'm not sure how to make them communicate in groups of 2 like in a peer-to-peer connection.
class Server {
private static DatagramSocket socket = null;
private static Map<Session, Integer> sessions = new HashMap<Session, Integer>();
private static Session session = new Session();
public static void main(String[] args) {
try {
socket = new DatagramSocket(6066);
} catch (SocketException e) {
System.out.println("[SERVER] Unable to launch server on port: " + socket.getLocalPort());
}
System.out.println("[SERVER] Server launched successfully on port " + socket.getLocalPort());
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
byte[] buffer = new byte[100];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
Arrays.fill(buffer, (byte) 0);
try {
socket.receive(packet);
} catch (IOException e) {
System.out.println("[SERVER] Unable to receive packets from buffer");
}
InetAddress ip = packet.getAddress();
int port = packet.getPort();
String data = new String(packet.getData()).trim();
if(session.getIp1() == null) {
session.setIp1(ip);
session.setPort1(port);
session.setData1(data);
} else {
session.setIp2(ip);
session.setPort2(port);
session.setData2(data);
}
DatagramPacket pt = new DatagramPacket(packet.getData(), packet.getData().length, ip, port);
try {
socket.send(pt);
} catch (IOException e) {
System.out.println("[SERVER] Unable to send packets to client.");
}
}
}
});
thread.start();
}
}
Client:
public class Client {
private static DatagramSocket socket = null;
public static void main(String[] args) {
System.out.println("Send to server:");
Scanner scanner = new Scanner(System.in);
while (true) {
try {
// port shoudn't be the same as in TCP but the port in the datagram packet must
// be the same!
socket = new DatagramSocket();
} catch (SocketException e1) {
System.out.println("[CLIENT] Unable to initiate DatagramSocket");
}
InetAddress ip = null;
try {
ip = InetAddress.getByName("127.0.0.1");
} catch (UnknownHostException e) {
System.out.println("[CLIENT] Unable to determine server IP");
}
// must be in a while loop so we can continuously send messages to server
String message = null;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
receive();
}
});
thread.start();
while (scanner.hasNextLine()) {
message = scanner.nextLine();
byte[] buffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, ip, 6066);
try {
socket.send(packet);
} catch (IOException e) {
System.out.println("[CLIENT] Unable to send packet to server");
}
}
}
}
private static void receive() {
// receiving from server
byte[] buffer2 = new byte[100];
DatagramPacket ps = new DatagramPacket(buffer2, buffer2.length);
while (true) {
try {
socket.receive(ps);
} catch (IOException e) {
System.out.println("[CLIENT] Unable to receive packets from server.");
}
System.out.println("[SERVER] " + new String(ps.getData()));
}
}
}
Object class:
public class Session {
private InetAddress ip1;
private int port1;
private String data1;
private InetAddress ip2;
private int port2;
private String data2;
public Session() {
}
public InetAddress getIp1() {
return ip1;
}
public void setIp1(InetAddress ip1) {
this.ip1 = ip1;
}
public int getPort1() {
return port1;
}
public void setPort1(int port1) {
this.port1 = port1;
}
public String getData1() {
return data1;
}
public void setData1(String data1) {
this.data1 = data1;
}
public InetAddress getIp2() {
return ip2;
}
public void setIp2(InetAddress ip2) {
this.ip2 = ip2;
}
public int getPort2() {
return port2;
}
public void setPort2(int port2) {
this.port2 = port2;
}
public String getData2() {
return data2;
}
public void setData2(String data2) {
this.data2 = data2;
}
}
Currently, you store the client's information in an array. Make an object where it will contain two client session's data. When a new client is attempting to connect, see if there are any objects that have a free spot, if not, create a new object and await a new participant; otherwise, join an existing session.
Hackish way: Create a Map<ObjectHere, UserCount> then filter based on userCounts = 1 and then join the session to the first returned Object.

Server-Client in UDP

My Datagram simple client server program is giving error.Client takes information from server and server also gets information from client.
Here is my Server:
package udp;
import java.net.*;
public class DatagramServer implements Runnable {
DatagramPacket pack;
DatagramSocket sock;
DatagramServer() {
new Thread(this).start();
}
public void run() {
try {
while (true) {
recieve();
send();
}
} catch (Exception e) {
System.out.println(e);
}
}
public void send() throws Exception {
byte data[] = "This is a \n datagram packet".getBytes();
InetAddress add = InetAddress.getByName("localhost");
pack = new DatagramPacket(data, data.length, add, 8000);
sock = new DatagramSocket();
sock.send(pack);
sock.close();
}
public void recieve() throws Exception {
byte[] buffer = new byte[65536];
DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
sock = new DatagramSocket(8000);
sock.receive(incoming);
byte[] data = incoming.getData();
String s = new String(data, 0, incoming.getLength());
}
public static void main(String[] args) {
new DatagramServer();
}
}
And here is my Client :
package udp;
import java.net.*;
public class DatagramClient {
DatagramPacket pack;
DatagramSocket sock;
DatagramClient() {
Thread t1 = new Thread() {
public void run() {
while (true) {
try {
receive();
Thread.sleep(5000);
} catch (Exception e) {
System.out.println(e);
}
}
}
};
t1.start();
Thread t2 = new Thread() {
public void run() {
while (true) {
try {
send();
Thread.sleep(5000);
} catch (Exception e) {
System.out.println(e);
}
}
}
};
t2.start();
}
public void receive() throws Exception {
byte data[] = new byte[1000];
pack = new DatagramPacket(data, data.length);
sock = new DatagramSocket(8000);
sock.receive(pack);
System.out.println("Data::" + new String(pack.getData(), "UTF-8"));
System.out.println("Port::" + pack.getPort());
sock.close();
}
public void send() throws Exception {
String s = "KOLI SDF DFEF XFFFSS";
byte[] b = new byte[1000];
b = s.getBytes();
DatagramPacket dp = new DatagramPacket(b, b.length, InetAddress.getByName("localhost"), 8000);
sock= new DatagramSocket(8000);
sock.send(dp);
}
public static void main(String[] args) {
new DatagramClient();
}
}
I'm getting errors like:
java.net.BindException: Address already in use: Cannot bind
java.net.BindException: Address already in use: Cannot bind
java.net.BindException: Address already in use: Cannot bind
java.net.BindException: Address already in use: Cannot bindBUILD STOPPED (total time: 4 seconds)
What should i do?
Your client and server has some issues such as open same port 8000 in different threads so I have fixed those within the following code.
Client
package udp;
import java.net.*;
public class DatagramClient {
DatagramPacket pack;
DatagramSocket sock;
DatagramClient() {
Thread t1 = new Thread() {
public void run() {
while (true) {
try {
receive();
Thread.sleep(5000);
} catch (Exception e) {
System.out.println(e);
}
}
}
};
t1.start();
}
public void receive() throws Exception {
byte data[] = new byte[1000];
pack = new DatagramPacket(data, data.length);
sock = new DatagramSocket(8000);
sock.receive(pack);
System.out.println("Data::" + new String(pack.getData(), "UTF-8"));
System.out.println("Port::" + pack.getPort());
sock.close();
}
public void send() throws Exception {
String s = "KOLI SDF DFEF XFFFSS";
byte[] b = new byte[1000];
b = s.getBytes();
DatagramPacket dp = new DatagramPacket(b, b.length, InetAddress.getByName("localhost"), 8000);
sock= new DatagramSocket(8000);
sock.send(dp);
}
public static void main(String[] args) {
new DatagramClient();
}
}
Server
package udp;
import java.net.*;
public class DatagramServer implements Runnable {
DatagramPacket pack;
DatagramSocket sock;
DatagramServer() {
new Thread(this).start();
}
public void run() {
try {
while (true) {
//recieve();
send();
}
} catch (Exception e) {
System.out.println(e);
}
}
public void send() throws Exception {
byte data[] = "This is a \n datagram packet".getBytes();
InetAddress add = InetAddress.getByName("localhost");
pack = new DatagramPacket(data, data.length, add, 8000);
sock = new DatagramSocket();
sock.send(pack);
sock.close();
}
public void recieve() throws Exception {
byte[] buffer = new byte[65536];
DatagramPacket incoming = new DatagramPacket(buffer, buffer.length);
sock = new DatagramSocket(8000);
sock.receive(incoming);
byte[] data = incoming.getData();
String s = new String(data, 0, incoming.getLength());
}
public static void main(String[] args) {
new DatagramServer();
}
}
The problem is your server code is trying to bind to the 8000 port each time receive () called. And receive is being called repeatedly from within the while(true) loop. So it tries to bind to the same port again and again.
To fix it remove the UDP socket instantiation i.e
sock = new DatagramSocket(8000);
From the receive method and put it before your while loop begins.

Server stuck in reading the buffer Java

I have a problem with a multi-connected server TCP. It accepts connection to client, but it stuck when it must read data (array of bytes[]) in InputBuffer.
The code is follow:
Server:
public class thread_acc extends Thread{
private final ServerSocket sock_acc;
public thread_acc() throws IOException {
this.sock_acc = new ServerSocket(10000);
}
#Override
public void run(){
for(;;){
try {
Socket sock_client = sock_acc.accept();
System.out.println("connection accepts");
new Thread(new thread_proc(sock_client)).start();
} catch (IOException ex) { Logger.getLogger(thread_acc.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class thread_proc implements Runnable{
private Socket sock_client;
public thread_proc(Socket sock){
this.sock_client = sock;
}
#Override
public void run(){
try {
procRequest();
} catch (IOException ex) {
Logger.getLogger(thread_proc.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(thread_proc.class.getName()).log(Level.SEVERE, null, ex);
}
}
void procRequest() throws IOException, ClassNotFoundException{
byte[] pack1 = socket.readSocket(sock_client);
System.out.println("read pack 1");
byte[] pack2 = socket.readSocket(sock_client);
System.out.println("read pack 2");
.....
}
Client:
public class thread_key implements Runnable {
private static InetAddress IpServer = InetAddress.getByName("127.0.0.1");
private static int PortServer = 10000;
private Socket sock_send;
private int id;
private String namefile;
public thread_key(int id, String namefile) throws IOException {
this.sock_send = new Socket(IpServer, PortServer);
this.id = id;
this.namefile = namefile;
}
#Override
public void run(){
Request();
}
private String[] Request(int iddoc) throws IOException, ClassNotFoundException{
...generations Keys RSA and payloads....
byte[] pack1 = RSA.encryptPub(payload1, pub);
byte[] pack2 = RSA.encryptPub(payload2, pub);
socket.writeSocket(sock_send, pack1);
socket.writeSocket(sock_send, pack2);
System.out.println("write ok");
}
}
Read and Write:
public class socket {
public static void writeSocket(Socket sock, byte[] pacchetto) throws IOException{
ObjectOutputStream out = new ObjectOutputStream(sock.getOutputStream());
out.writeObject(pacchetto);
out.flush();
}
public static byte[] readSocket(Socket sock) throws IOException, ClassNotFoundException{
ObjectInputStream in = new ObjectInputStream(sock.getInputStream());
byte[] pacchetto = (byte[]) in.readObject();
return pacchetto;
}
}
Don't create new object streams every time you want to send or receive something. Use the same streams for the life of the socket, at both ends. Object streams have headers which are read or written on construction, so if construction at the receiver doesn't match construction at the sender, errors will ensue.

Netty server stops responding

I have ServerHandshakeHandler which extends ChannelInboundHandlerAdapter. Client emulates multiple access to server. After some time of successful communication server stops responding when client tries to connect. It doesn't show any incoming connections. Client restart doesn't help, only restart of server.
I tried to set telnet connection when server stops responding: connection establishes but I can't get any response from server (when server is in normal state, it sends response). Similar situation with nmap -v --packet-trace -sT localhost -p {port} : nmap discovers port as open, but there is no log information about incoming connection on server.
Server:
public class ServerHandshakeHandler extends ChannelInboundHandlerAdapter {
private final ChannelGroup group;
private static final byte HANDSHAKE_SUCCEDED = 1;
private static final byte HANDSHAKE_FAILED = 0;
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public ServerHandshakeHandler(ChannelGroup group) {
this.group = group;
}
#Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
LOG.debug("in ServerHandshakeHandler.channelRead");
ByteBuf buf = (ByteBuf) msg;
String someField = getSomeField(buf);
ReferenceCountUtil.release(msg);
if (someField.isEmpty()) {
this.fireHandshakeFailed(ctx);
return;
}
LOG.debug("Removing handshake handler from pipeline.");
ctx.pipeline().remove(this);
this.fireHandshakeSucceeded(ctx);
}
#Override
public void channelActive(final ChannelHandlerContext ctx) {
LOG.debug("in ServerHandshakeHandler.channelActive, group size = " + this.group.size());
this.group.add(ctx.channel());
LOG.debug("Incoming connection from: {}",
ctx.channel().remoteAddress().toString());
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
LOG.error("exception caught ", cause);
if (ctx.channel().isActive()) {
ctx.channel().close();
} else {
this.fireHandshakeFailed(ctx);
}
}
private void fireHandshakeFailed(ChannelHandlerContext ctx) {
LOG.debug("fire handshake failed");
ByteBuf buf = Unpooled.buffer(1);
buf.writeByte(HANDSHAKE_FAILED);
ctx.channel().writeAndFlush(buf);
ctx.channel().close();
ctx.fireUserEventTriggered(HandshakeEvent.handshakeFailed(ctx.channel()));
}
private void fireHandshakeSucceeded(ChannelHandlerContext ctx) {
LOG.debug("fire handshake succeded");
ByteBuf buf = Unpooled.buffer(1);
buf.writeByte(HANDSHAKE_SUCCEDED);
ctx.channel().writeAndFlush(buf);
ctx.fireUserEventTriggered(HandshakeEvent
.handshakeSucceeded(ctx.channel()));
}
}
Client:
public class MyClient {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private String host;
private int port;
private Socket socket;
public Client(String host, int port) {
this.host = host;
this.port = port;
}
public void send(String id, String message) {
try {
socket = new Socket(host, port);
LOG.debug("connected to server");
if (performHandshake(id)) {
LOG.debug("handshake success");
sendMessage(message);
}
socket.close();;
} catch (IOException ex) {
LOG.error("error while sending data", ex);
}
}
private boolean performHandshake(String id) {
try {
byte[] request = handshakeRequest(id);
writeBytes(request);
byte[] response = readBytes(1);
return (response != null && response.length == 1 && response[0] == 1);
} catch (IOException ex) {
LOG.error("perform handshake error", ex);
return false;
}
}
private byte[] handshakeRequest(String id) throws UnsupportedEncodingException {...}
private void writeBytes(byte[] data) throws IOException {
OutputStream out = socket.getOutputStream();
out.write(data);
}
private byte[] readBytes(int length) throws IOException {
InputStream in = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[1024];
int currentLength = 0;
while (currentLength < length) {
int size = in.read(buffer); //here client stops waiting server response
if (size == -1) {
throw new IOException("unexpected end of stream");
}
baos.write(buffer, 0, size);
currentLength += size;
}
return baos.toByteArray();
}
}
SOLVED! There was narrow piece of code where I was calling synchronized function with connection to database. This connection cannot be established for some reasons and the function hangs. Thread in this function goes into WAITING state. After a while other treads try to access this function and become BLOCKED. That's why server stops processing incoming connections.
I recommend jvisualvm profiling tool, it helped me to find this bug.

Send object via socket

I want to send x object over socket but when I run this code i got nothings.
it is stop at new ObjectInputStream(socket.getInputStream())
and don't do any thing else.
Server class:
public class Server {
private static final int PORT = 9001;
ServerSocket listener;
private Handler h[] = new Handler[5];
private int clientCount = 0;
public Server() throws Exception{
System.out.println("The server is running.");
listener = new ServerSocket(PORT);
run();
}
public void run(){
while (true) {
try {
addClient(listener.accept());
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void addClient(Socket socket) throws Exception{
h[clientCount] = new Handler(this, socket,clientCount);
h[clientCount].open();
clientCount++;
}
public static void main(String[] args) throws Exception {
Server s = new Server();
}
}
Handler class // Handle class:
public class Handler extends Thread {
private Server server;
private Socket socket;
private int ID = -1;
private ObjectInputStream obIn = null;
private ObjectOutputStream obOut = null;
public Handler(Server _server, Socket _socket, int i){
super();
server = _server;
socket = _socket;
ID = i;
}
public void open()
{
try {
obIn = new ObjectInputStream(socket.getInputStream());
obOut = new ObjectOutputStream(socket.getOutputStream());
x= ob.readObject();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The client:
public class Client {
ObjectInputStream oin;
ObjectOutputStream oot;
private Socket socket = null;
public Client() {
String serverAddress = "127.0.0.1";
try {
socket = new Socket(serverAddress, 9001);
oin = new ObjectInputStream(socket.getInputStream());
oot = new ObjectOutputStream(socket.getOutputStream());
System.out.println("hello i am a client");
oot.writeObject(x);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
Client client = new Client();
}
}
You must declare the ObjectOutputStream before you declare the ObjectInputStream.
When you create an ObjectInputStream, it waits for data from an ObjectOutputStream. It's waiting on that data (the header).
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
enableOverride = false;
readStreamHeader(); //this is whats causing it to block
bin.setBlockDataMode(true);
}
protected void readStreamHeader() throws IOException, StreamCorruptedException {
short s0 = bin.readShort();
short s1 = bin.readShort();
if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
throw new StreamCorruptedException(String.format("invalid stream header: %04X%04X", s0, s1));
}
}
If you declare ObjectOutputStream first, it sends the data, which isn't blocking

Categories