I'm passing an integer to DatagramSocket's constructor though MyDatagramSocket, but I get the error: "address already in use: Cannot bind". I'm running the client from NetBeans and the Server from a terminal. I've tried several different ports, restarted Netbeans - shut down the terminal, and even tried restarting the computer.
I try to find the port with netstat, but i don't even find it there. Here is my code:
Client.java
package datagramcounterserver;
import java.io.*;
public class Client {
public static void main(String[] args) {
InputStreamReader is = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(is);
try {
System.out.println("Welcome to the Daytime client. \n" + "What is the name of the server host?");
String hostName = br.readLine();
if (hostName.length() == 0)
hostName = "localhost";
System.out.println("What is the port number of the server host?");
String portNum = br.readLine();
if (portNum.length() == 0) {
portNum = "223";
}
System.out.println("Counter receiver from the server: " + Helper.getCounter(hostName, portNum));
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
Helper.java
package datagramcounterserver;
import java.net.*;
import java.net.InetAddress;
public class Helper {
public static int getCounter(String hostName, String portNum) {
int counter = 0;
String message = "1";
try {
InetAddress serverHost = InetAddress.getByName(hostName);
int serverPort = Integer.parseInt(portNum);
MyDatagramSocket mySocket = new MyDatagramSocket(serverPort);
mySocket.sendMessage(serverHost, serverPort, " ");
message = mySocket.receiveMessage();
System.out.println("Message received: " + message);
counter = Integer.parseInt(message.trim());
mySocket.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
return counter;
}
}
MyDatagramSocket.java
package datagramcounterserver;
import java.net.*;
import java.io.*;
public class MyDatagramSocket extends DatagramSocket {
final int MAX_LEN = 10;
MyDatagramSocket(int portNo) throws SocketException {
super(portNo);
}
public void sendMessage(InetAddress receiverHost, int receiverPort, String message) throws IOException {
byte[] sendBuffer = message.getBytes();
DatagramPacket datagram = new DatagramPacket(sendBuffer, sendBuffer.length, receiverHost, receiverPort);
this.send(datagram);
}
public String receiveMessage() throws IOException {
byte[] receiveBuffer = new byte[MAX_LEN];
DatagramPacket datagram = new DatagramPacket(receiveBuffer, MAX_LEN);
this.receive(datagram);
String message = new String(receiveBuffer);
return message;
}
}
MyServerDatagraphSocket.java
package datagramcounterserver;
import java.net.*;
import java.io.*;
public class MyServerDatagramSocket extends DatagramSocket {
static final int MAX_LEN = 100;
MyServerDatagramSocket(int portNo) throws SocketException {
super(portNo);
}
public void sendMessage(InetAddress receiverHost, int receiverPort, String message) throws IOException {
byte[] sendBuffer = message.getBytes();
DatagramPacket datagram = new DatagramPacket(sendBuffer, sendBuffer.length, receiverHost, receiverPort);
this.send(datagram);
}
public String receiveMessage() throws IOException {
byte[] receiveBuffer = new byte[MAX_LEN];
DatagramPacket datagram = new DatagramPacket(receiveBuffer, MAX_LEN);
this.receive(datagram);
String message = new String(receiveBuffer);
return message;
}
public DatagramMessage receiveMessageAndSender() throws IOException {
byte[] receiveBuffer = new byte[MAX_LEN];
DatagramPacket datagram = new DatagramPacket(receiveBuffer, MAX_LEN);
this.receive(datagram);
DatagramMessage returnVal = new DatagramMessage();
returnVal.putVal(new String(receiveBuffer), datagram.getAddress(), datagram.getPort());
return returnVal;
}
}
Server.java
package datagramcounterserver;
import java.io.*;
public class Server {
static int counter = 0;
public static void main(String[] args) {
int serverPort = 223;
if (args.length == 1)
serverPort = Integer.parseInt(args[0]);
try {
MyServerDatagramSocket mySocket = new MyServerDatagramSocket(serverPort);
System.out.println("Counter server ready.");
while (true) {
DatagramMessage request = mySocket.receiveMessageAndSender();
System.out.println("Request received");
increment();
System.out.println("counter sent "+ counter);
mySocket.sendMessage(request.getAddress(), request.getPort(), String.valueOf(counter));
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}
static private synchronized void increment() {
counter++;
}
}
Both your server and your client are binding to the port, and the second one to launch fails to bind. The DatagramSocket
constructor that takes a single int parameter is the equivalent of creating a DatagramSocket and calling socket.bind(port)
.
While this is the behaviour you want on your server, on the client you do not want to bind to the port - you want to connect to the server. This is done instead by using the connect() method. You probably want to change your MyDatagramSocket
class' constructor to something like this:
MyDatagramSocket(String address, int portNo) throws SocketException {
super();
connect(InetAddress.getByName(address), portNo);
}