Am new to Socket programming am trying to establish a communication between a Server and a client but i don't know how to do that am a bit confused on how to go about it. I have written the program below but it is given error and i can't get my head round why.
package server;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Server {
public static void main(String[] args) {
// TODO code application logic here
try {
DatagramSocket socket = new DatagramSocket(7000);
socket.setSoTimeout(0);
while(true)
{
byte []buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
socket.receive(packet);
String message = new String (buffer);
System.out.println(message);
String Reply ="Am here";
DatagramPacket data = new DatagramPacket(Reply.getBytes(), Reply.getBytes().length, packet.getAddress(), packet.getPort());
socket.send(data);
}
}
catch (Exception error){
error.printStackTrace();
}
}
}
Client
package client;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Client {
public static void main(String[] args) {
// TODO code application logic here
try{
String message = "Hello Server";
String host = "localhost";
InetAddress addr = InetAddress.getByName(host);
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 7000);
DatagramSocket socket = new DatagramSocket(4000);
socket.send(packet);
DatagramSocket sockets = new DatagramSocket(7000);
sockets.setSoTimeout(0);
while(true)
{
byte []buffer = new byte[1024];
DatagramPacket packets = new DatagramPacket(buffer,buffer.length);
sockets.receive(packets);
String messages = new String (buffer);
System.out.println(messages);
}
}
catch (Exception error){
error.printStackTrace();
}
}
}
How can i get them communicated. I have heard about Multi-threading but can't get my head round how it works.
I get the following error.
java.net.BindException: Address already in use: Cannot bind
at java.net.DualStackPlainDatagramSocketImpl.socketBind(Native Method)
at java.net.DualStackPlainDatagramSocketImpl.bind0(DualStackPlainDatagramSocketImpl.java:84)
at java.net.AbstractPlainDatagramSocketImpl.bind(AbstractPlainDatagramSocketImpl.java:93)
at java.net.DatagramSocket.bind(DatagramSocket.java:392)
at java.net.DatagramSocket.<init>(DatagramSocket.java:242)
at java.net.DatagramSocket.<init>(DatagramSocket.java:299)
at java.net.DatagramSocket.<init>(DatagramSocket.java:271)
at client.Client.main(Client.java:32)
If you wanting to send/receive from a client to a server using a socket then use ServerSocket on the serverside.
Then use accept - This listens for a connection to be made to this socket and accepts it.
The Socket object returned by Accept has Input and Output Stream which can be be read and written to.
The client will just use a Socket Object
See http://cs.lmu.edu/~ray/notes/javanetexamples/ for an example
If for some reason you insist on using DatagramSocket, then see this example https://docs.oracle.com/javase/tutorial/networking/datagrams/clientServer.html
The error occurs because the port you are trying to bind your socket to is already in use. Port 7000 is used both by the client and server:
DatagramSocket sockets = new DatagramSocket(7000);
Related
I am doing a server and client socket datagram.
The client connects to the server and you need to write in the client a string that contains Hello or hello.
When the server detects a string with hello or Hello, repplies to the client with another string.
The problem is that the client doesn't read the string that the server sends.
Here is my code.
Client
public class Client {
public static void main(String[] args) {
try {
System.out.println("Creando socket datagram");
DatagramSocket datagramSocket = new DatagramSocket();
Scanner myObj = new Scanner(System.in); // Create a Scanner object
System.out.println("Say Hello");
String saludo = myObj.nextLine();
System.out.println("Sending message");
InetAddress addr = InetAddress.getByName("localhost");
DatagramPacket datagrama = new DatagramPacket(saludo.getBytes(), saludo.getBytes().length, addr, 5555);
datagramSocket.send(datagrama);
System.out.println("Message sent");
System.out.println("Reading message");
byte[] mensaje = new byte[25];
DatagramPacket datagrama1 = new DatagramPacket(mensaje, 25);
datagramSocket.receive(datagrama1);
System.out.println("Message recieved: " + new String(mensaje));
System.out.println("Closing");
datagramSocket.close();
System.out.println("FInished");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server
public class Server {
public static void main(String[] args) throws InterruptedException {
try {
for (;;) {
System.out.println("Creating socket datagram");
InetSocketAddress addr = new InetSocketAddress("localhost", 5555);
DatagramSocket datagramSocket = new DatagramSocket(addr);
System.out.println("RReading message");
byte[] mensaje = new byte[25];
DatagramPacket datagrama1 = new DatagramPacket(mensaje, 25);
datagramSocket.receive(datagrama1);
System.out.println("Message recieved: " + new String(mensaje));
if (new String(mensaje).contains("hello") || new String(mensaje).contains("Hello")) {
String quetal = "¿Hello, how are you doing?";
System.out.println("Sending message");
TimeUnit.SECONDS.sleep(2);
DatagramPacket datagrama2 = new DatagramPacket(quetal.getBytes(), quetal.getBytes().length, addr.getAddress(),
5555);
datagramSocket.send(datagrama2);
System.out.println("Message Sent");
}
datagramSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have tried putting a sleep in the server in case the server sends the string before the client tries to read.
Many thanks for the help as always.
The client is using the parameter-less DatagramSocket() constructor to bind to a random port with which to send and receive on:
Constructs a datagram socket and binds it to any available port on the local host machine. The socket will be bound to the wildcard address, an IP address chosen by the kernel.
However, when the server receives a datagram, you are ignoring the IP and port where the datagram was actually sent from:
DatagramSocket.receive(DatagramPacket)
Receives a datagram packet from this socket. When this method returns, the DatagramPacket's buffer is filled with the data received. The datagram packet also contains the sender's IP address, and the port number on the sender's machine.
When the server is sending the reply, you are sending it back to the server itself at localhost:5555, not to the client at all.
On the server side, you need to change this:
DatagramPacket datagrama2 = new DatagramPacket(..., addr.getAddress(), 5555);
To either this:
DatagramPacket datagrama2 = new DatagramPacket(..., datagrama1.getAddress(), datagrama1.getPort());
Or to this:
DatagramPacket datagrama2 = new DatagramPacket(..., datagrama1.getSocketAddress());
On a side note, your server is also ignoring the actual length of the data that is being sent by the client. The server is receiving data using a 25-byte array, but the client may not actually be sending 25 bytes. If the client sends less than 25 bytes, you will end up with a String that contains random garbage on the end of it. And if the client sends more than 25 bytes, `receive() will truncate the data.
Try something more like this instead:
System.out.println("Reading message");
byte[] buffer = new byte[65535];
DatagramPacket datagrama1 = new DatagramPacket(buffer, buffer.length);
datagramSocket.receive(datagrama1);
String mensaje = new String(datagrama1.getData(), datagrama1.getLength());
System.out.println("Message recieved: " + mensaje);
if (mensaje.contains("hello") || mensaje.contains("Hello")) {
...
}
This was fun :)
Kindly keep in mind, the way this is coded might not be the best, however it works as you want.
The Client sends Hello, The server receives Hello, and Sends (Hello back at you).
Both then terminate. It doesnt keep on looping those 2 messages forever, but I showed you the idea.
The Server needs to act as a Client as well in order to send messages.
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class DReceiver{
public static void replyToTheClientListening() throws IOException {
DatagramSocket ds = new DatagramSocket();
String str = "hello back at you";
InetAddress ia = InetAddress.getByName("127.0.0.1");
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), ia, 3001);
ds.send(dp);
ds.close();
}
public static void listenToMessagesFromTheClient() throws IOException {
DatagramSocket ds = new DatagramSocket(3000);
ds.setSoTimeout(60000); //Wait 60 SECONDS for messages
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
ds.receive(dp);
String strRecv = new String(dp.getData(), 0, dp.getLength());
if("hello".equalsIgnoreCase(strRecv)) { //hello in any case
System.out.println("Received a MSG from the Client " + strRecv);
replyToTheClientListening();
}
ds.close();
}
public static void main(String[] args) throws Exception {
listenToMessagesFromTheClient();
}
}
The DSender is a Client but also needs to act as a Server (To Listen to Messages coming in from the other Server)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class DSender{
public static void actAsAServerAndListenToMessages() throws IOException {
//Listen to Port 3001 --The Server will send to that port
DatagramSocket dsReceive = new DatagramSocket(3001);
dsReceive.setSoTimeout(60000); //Make it wait 60 SECONDS
byte[] buf = new byte[1024];
DatagramPacket dpReceive = new DatagramPacket(buf, 1024);
dsReceive.receive(dpReceive);
String strRecv = new String(dpReceive.getData(), 0, dpReceive.getLength());
System.out.println("Client -- Received a Msg back from Server --" + strRecv);
dsReceive.close();
}
public static void sendAMessageAsAClientToTheServer() throws IOException {
// Client will send a message to Port 3000 which the Server listens to.
DatagramSocket ds = new DatagramSocket();
String str = "hello";
InetAddress ia = InetAddress.getByName("127.0.0.1");
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), ia, 3000);
ds.send(dp);
ds.close();
}
public static void main(String[] args) throws Exception {
sendAMessageAsAClientToTheServer();
actAsAServerAndListenToMessages();
}
}
Reference :
https://www.javatpoint.com/DatagramSocket-and-DatagramPacket
I run the server, then the Client.
Edit: I made a boiled down version of my code which seems to have the same problem:
import java.net.*;
public class TEST {
public static void main(String[] args) {
//message1
String s = "bla";
try{
testServer t = new testServer();
Thread serve = new Thread(t);
serve.start();
DatagramSocket sock = new DatagramSocket();
sock.connect(InetAddress.getLocalHost(),54636);
DatagramPacket dp = new DatagramPacket(s.getBytes(),s.getBytes().length);
//Thread.sleep(2000);
System.out.println("sending message");
sock.send(dp);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
class testServer implements Runnable{
public void run(){
try{
DatagramSocket socket = new DatagramSocket();
socket.connect(InetAddress.getLocalHost(),54636);
byte[] buf = new byte[500];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
System.out.println("Server waits for message.");
socket.receive(dp);
String a = new String(dp.getData());
System.out.println(a);
}catch(Exception e){
System.err.println(e.getMessage());
e.printStackTrace();
}
}
}
I have a server thread that connects to a Datagram Socket (localhost, 54636(<-random)). Then I try to send a message to the server, but it does not receive it.
P.S.: sry that I am so unspecific, but I have no idea what's causing the problem :( and thank you for your help :)
In testServer replace the following lines:
DatagramSocket socket = new DatagramSocket();
socket.connect(InetAddress.getLocalHost(),54636);
with:
DatagramSocket socket = new DatagramSocket(InetAddress.getLocalHost(),54636);
Edit:
I strongly suggest you take a look at Writing a Datagram Client and Server Java trail for more info on how datagram socket programming works.
You simply were not using the API correctly.
I have a problem to run a server and clients in one (mac) machine. I can run the server but when I run the client it give me an error java.net.BindException: Address already in use
at java.net.PlainDatagramSocketImpl.bind0(Native Method)
as far as I know that there is somthing call ssh that need to be used but I don't know how to use it to do solve this.
Thanks
public class WRRCourseWork {
public static void main(String[] args) {
try {
DatagramSocket IN_socket = new DatagramSocket(3000);
DatagramSocket OUT_socket = new DatagramSocket(5000);
IN_socket.setSoTimeout(0);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
//recive the message
IN_socket.receive(packet);
String message = new String(buffer);
System.out.println("Got message: " + message.trim());
// send the message
String host = "";
InetAddress addr = InetAddress.getByName(host);
DatagramPacket OUT_Packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 5000);
OUT_socket.send(OUT_Packet);
System.out.println("Sending Message: "+ message.trim());
}
} catch (Exception error) {
error.printStackTrace();
}
}
...
public class Messages {
public static void main(String [] args) {
System.out.println("hiiiiiii");
//String host = "localhost";
try {
while (true) {
InetAddress addr = InetAddress.getLocalHost();
String message = "Hello World";
DatagramPacket packet = new DatagramPacket(message.getBytes(), message.getBytes().length, addr, 4000);
DatagramSocket socket = new DatagramSocket(4000);
socket.send(packet);
//socket.close();
}
} catch(Exception error) {
// catch all errors
error.printStackTrace();
}
}
}
There are a few things that you might want to change here:
1) You are sending a UDP packet on port 4000 from your client but listening on port 3000 in your server(receiver) code. Ports should be same.
2) There might be another instance of your server code running in another Netbeans tab or from your terminal may be, which is already bound to the port. Please ensure that you have only one instance running for your server code. This will resolve your 'Address already in use error'
3) I also added 'Thread.sleep(500)' in the client(sender) code in the infinite while loop that you have set up. Without this, the code was ending up with a 'Bad File Descriptor' error on my machine. Probably it was a conflict with the Socket handle running into a problem with the infinite loop in place.
With these changes, data exchange between client and server is working fine.
i tried my hands on networking and this is the first time i have understood some bit of it.i have a program with a client and server.What i want to do is that the server should send data continuously to a port and whenever there is any data in port say 2656 ,the client should read the data from that port and the data should be flushed from the port.I have created a server program and a client program but the client is not receiving any packet.I m running client and server on two different machines.
Server Program
import java.io.*;
import java.net.*;
public class Server{
public static void main(String args[]) throws Exception {
DatagramSocket dsocket = new DatagramSocket();
try {
String host = "192.168.0.15";
int count =1;
byte[] message = "Java Source and Support".getBytes();
// Get the internet address of the specified host
InetAddress address = InetAddress.getByName(host);
// Initialize a datagram packet with data and address
for(;;)
{
DatagramPacket packet = new DatagramPacket(message, message.length,
address, 2656);
// Create a datagram socket, send the packet through it, //close it.
System.out.println("Sending data"+message.toString();
dsocket.send(packet);
}
} catch (Exception e) {
System.err.println(e);
}
finally
{
dsocket.close();
}
}
}
Client program
package saturdayTest;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPReceive {
public static void main(String args[]) {
try {
int port = 2656;
// Create a socket to listen on the port.
DatagramSocket dsocket = new DatagramSocket(port);
byte[] buffer = new byte[2048];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
while (true) {
System.out.println("Waiting for a packer");
dsocket.receive(packet);
String msg = new String(buffer, 0, packet.getLength());
System.out.println(packet.getAddress().getHostName() + ": "
+ msg);
packet.setLength(buffer.length);
}
} catch (Exception e) {
System.err.println(e);
}
}
}
I've been working on different ways to do this for 2 full coding days, i need some help:
I want to create a multiplayer game in java online. To do this i need communication between the server and the applet
I was under the impression that as long as the UDP server is being ran on the same machine the applet is being hosted on, it would work. (perhaps i need to be corrected on that)
I continually get this error on the error console (from applet)
java.security.AccessControlException: access denied (java.net.SocketPermission 127.0.0.1:5556 connect,resolve)
When trying to receive messages on the applet, nothing happens, nothing is sent and nothing is received (the udp server is sending a message,applet is not receiving, i know the udp is sending correctly as i tested separately it with a client)
Here is the UDPclient.java applet:
``
import java.io.*;
import java.net.*;
import java.applet.*;
public class UDPClient extends Applet
{
protected DatagramSocket socket = null;
protected DatagramPacket packet = null;
String ipAddress;
public void init()
{
try{
System.out.println("got username");
String username = getParameter("username");
System.out.println("got ip");
ipAddress = getParameter("ip");
System.out.println("makingsocket");
socket = new DatagramSocket();
System.out.println("sending packet");
sendPacket();
System.out.println("receiving packet");
receivePacket();
System.out.println("closing socket");
socket.close();
}catch(Exception e){e.printStackTrace();}
}
public void sendPacket() throws IOException
{
byte[] buf ="hihihi".getBytes(); // send hihihi
InetAddress address = InetAddress.getByName(ipAddress);
packet = new DatagramPacket(buf, buf.length, address, 5556);
System.out.println("sending packet");
socket.send(packet);
int port = packet.getPort();
}
public void receivePacket() throws IOException
{
byte[] buf = new byte[256];
packet = new DatagramPacket(buf, buf.length);
System.out.println("getting packet--- calling socket.receive");
socket.receive(packet);
System.out.println("got here, receiving packet");
String modifiedSentence =new String(packet.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
}
}
Here is the HTML file i run the applet with:
<applet code="UDPClient.class" width="640" height="480">
<param name="username" value="Guest">
<param name="ip" value="localhost">
</applet>
And here is the server i'm using
import java.io.*;
import java.net.*;
public class multiTest
{
static protected DatagramSocket socket = null;
static protected DatagramPacket packet = null;
public static void main(String [] args) throws IOException
{
socket = new DatagramSocket(5556);
while(true)
{
receivePacket();
sendPacket();
}
}
public static void receivePacket() throws IOException
{
//receive message from client
byte[] buf = new byte[256];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
//translate message in a thread
String message = new String(packet.getData(), 0, packet.getLength());
System.out.println("received" + message);
// should really make thread;
}
public static void sendPacket() throws IOException
{
byte[] buf = "ack".getBytes();
//send the message to the client to the given address and port
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);
}
}
I have been trying to follow the tutorial here :http://corvstudios.com/tutorials/udpMultiplayer.php to create this code.
i really didnt wanna have to end up using MINA, Tomcat or install any network framework - but if i have to let me know, it'll save me a lot of time
Any help is sincerely appreciated in advanced!
The JRE used by your applet need to be configured to authorize access thé file system to your applet. See policy or security for applet