I've written two programs. Now each program uses threading to send and receive packets at the same time.
Whenever I send packets from the server to the client, the message at the client ends gets received in an infinite loop. I.e; I've added a print statement that prints the message sent and this goes forever in an infinite loop. I want to make it so that it receives the message, and then be able to write back to the server and exit whenever the user wants to.
I've tried using socket.close(), but this makes it so that the client receives the message and I can only write back to the server once. After I send it, I can't send anymore. I want to make it so that I can write back more than once.
Can anyone please point me in the right direction?
My code is as follows;
public class UDPThreadClient extends Thread {
public static int port1;
//Create threaded server
UDPThreadClient (int port1) {
System.out.println ("Starting threaded client");
start();
}
public void run() {
int port = port1;
try {
DatagramSocket serverSocket = new DatagramSocket(port1);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
SocketAddress address = receivePacket.getSocketAddress();
System.out.println("RECEIVED from " + address + " : " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
//int port = receivePacket.getPort();
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
//serverSocket.close();
}
} catch (IOException e) {
System.out.println (e.getMessage());
}
}
//Create client
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
port1 = Integer.parseInt(args[1]);
new UDPThreadClient (port1);
try {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = inFromUser.readLine();
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
//clientSocket.close();
} catch (IOException e) {
System.out.println (e.getMessage());
}
}
}
and
public class UDPThreadServer extends Thread {
public static int port1;
//Create threaded client
UDPThreadServer () {
System.out.println ("Starting threaded server");
start();
}
public void run() {
try {
DatagramSocket clientSocket = new DatagramSocket();
BufferedReader inFromUser = new BufferedReader (new InputStreamReader(System.in));
Scanner in = new Scanner (inFromUser);
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte [1024];
byte[] receiveData = new byte [1024];
while (in.hasNextLine()) {
String sentence = in.nextLine();
//inFromUser.readLine();
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket (sendData, sendData.length, IPAddress, port1);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket (receiveData, receiveData.length);
clientSocket.receive (receivePacket);
String modSentence = new String (receivePacket.getData());
System.out.println ("FROM SERVER: " + modSentence);
}
//clientSocket.close();
} catch (IOException e) {
System.out.println (e.getMessage());
}
}
//Create server
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
port1 = Integer.parseInt(args[1]);
new UDPThreadServer ();
try {
DatagramSocket serverSocket = new DatagramSocket (port);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while (true) {
DatagramPacket receivePacket = new DatagramPacket (receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
SocketAddress address = receivePacket.getSocketAddress();
System.out.println ("Received from " + address + " : " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
String capSentence = sentence.toUpperCase();
sendData = capSentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket (sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
//serverSocket.close();
}
} catch (IOException e) {
System.out.println (e.getMessage());
}
}
}
Thanks.
Looking at UDPClientServer:
When you create the Datagram packet, you give it the port to send it to, not the port that you are sending it from.
When I ran your code, nothing happened. The server is waiting on port port, while the client sends to port port1. If you instead send to port port (not accessible from the main method, but changing it to a field instead of local method would fix that, then the infinite looping occurs because the server sends a packet to the same port it is listening on. There's your problem. Do you supply the same numbers as the first and second arguments to your program?
From the server, you can use receivePacket.getPort() to get the port where the packet came from.
EDIT:
Your two classes have much repetition, which is probably a source of confusion. One class has a main which starts a client then creates a server type loop tester. The other class sets up a Server then creates a client type tester.
Below is only the class you've named UDPThreadServer with comments showing changes to make the server 'work' with the testing code in the main method. Note that the server should send to a port that it is not listening to. You are also reading port values from command line arguments. I just made up some numbers for the ports and stuck them in as constants.
public class UDPThreadServer extends Thread
{
public static int port1;
UDPThreadServer()
{
//server or client? it's hard to say. you call the socket a clientSocket.
System.out.println("Starting threaded server");
start();
}
public void run()
{
try
{
// Here client(?) is set up with empty constructor.
// It is a mystery what port it will get.
DatagramSocket clientSocket = new DatagramSocket();
BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));
Scanner in = new Scanner(inFromUser);
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
while (in.hasNextLine())
{
String sentence = in.nextLine();
// inFromUser.readLine();
sendData = sentence.getBytes();
// sending to port1? that must be the server.
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port1);
clientSocket.send(sendPacket);
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER: " + modSentence);
}
// clientSocket.close();
} catch (IOException e)
{
System.out.println(e.getMessage());
}
}
// Create server
public static void main(String[] args)
{
// int port = Integer.parseInt(args[0]);
int port = 1927; // or whatever
// port1 = Integer.parseInt(args[1]);
port1 = 1928;
new UDPThreadServer();
try
{
// server resides on port1? if client sends to port 1, then this is so.
DatagramSocket serverSocket = new DatagramSocket(port1);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while (true)
{
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
SocketAddress address = receivePacket.getSocketAddress();
System.out.println("Received from " + address + " : " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
String capSentence = sentence.toUpperCase();
sendData = capSentence.getBytes();
// where did you get the info from? Client is set up with an empty constructor, so it is a mystery.
port = receivePacket.getPort();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
// serverSocket.close();
}
} catch (IOException e)
{
System.out.println(e.getMessage());
}
}
}
Don't close the socket.
If that doesn't answer your question you need to clarify it.
while(true) is an infinite loop. Do you quit it in any case?
Related
I have created 2 java programs, client pings the server and the server reply to client. The problem that I'm having is that the programs works fine when I tried to run both client and server on the same machine. But when I tried to run the client and the server separately (that is the client and servers on another machine in virtualbox) I'm getting no response from the server. Any help ?
Function for the client to send ping request
public static void ping(String serverIP, int numberOfPacketToSend,int setTimeOut,int sendDa){
int lossPacket = 0;
try {
String serverHostname = new String (serverIP);
BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName(serverHostname);
System.out.println ("connecting to " + IPAddress+"...");
byte[] sendData = new byte[sendDa];
byte[] receiveData = new byte[sendDa];
for(int i = 0;i<numberOfPacketToSend;i++){
String sentence = "Pinging "+serverIP;
//sendData = sentence.getBytes();
// System.out.println ("Sending data to " + sendData.length +
// " bytes to server.");
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
//System.out.println("data being send to server "+sendData.length);
clientSocket.send(sendPacket);
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
// System.out.println ("Waiting for return packet");
clientSocket.setSoTimeout(setTimeOut);
try {
clientSocket.receive(receivePacket);
String modifiedSentence =
new String(receivePacket.getData());
InetAddress returnIPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
// System.out.println ("From server at: " + returnIPAddress +
// ":" + port);
System.out.println("Reply from "+serverIP+" bytes="+sendData.length);
}
catch (SocketTimeoutException ste)
{
System.out.println ("Timeout Occurred: Packet assumed lost");
lossPacket ++;
}}
clientSocket.close();
}
catch (UnknownHostException ex) {
System.err.println(ex);
}
catch (IOException ex) {
System.err.println(ex);
}
System.out.println("Total loss packet = "+lossPacket);
System.out.println("Number of packet send ="+numberOfPacketToSend);
try{
System.out.println("Percentage packet loss ="+((numberOfPacketToSend/lossPacket)*100)+"%");
}catch(ArithmeticException e){System.out.println("Percentage packet loss = 0%");}
}
}
function for the server to wait for any connections
public static void waitForConnection(int portNumber, String ServerAddress) throws IOException{
try
{
InetAddress addr = InetAddress.getByName("5.5.5.5");
DatagramSocket serverSocket = new DatagramSocket(null);
InetSocketAddress address = new InetSocketAddress(ServerAddress, portNumber);
serverSocket.bind(address);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true)
{
receiveData = new byte[1024];
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
System.out.println ("Server up and running on port "+portNumber);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
System.out.println ("From: " + IPAddress + ":" + port);
System.out.println ("Message: " + sentence);
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress,
port);
serverSocket.send(sendPacket);
}
}
catch (SocketException ex) {
System.out.println("UDP Port 9876 is occupied.");
System.exit(1);
}
}
I'm trying to build a simple UDPServer and UDPClient. A String comparison doesn't work.
Here's what I got so far:
import java.io.*;
import java.net.*;
import java.util.concurrent.TimeUnit;
public class UDPSender
{
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(9877);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
boolean weiter = true;
do {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
/*I'm trying to make the if()-statement true, but the program always enters the else()-clause, no matter what I do.*/
if("Shutdown".equals(sentence)) {
weiter = false;
String bye = ("Auf Wiedersehen! Verbindung wird gekappt...");
sendData = bye.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
serverSocket.close();
} else {
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
} while(weiter);
}
}
And this is the client:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
class UDPClient{
public static void main(String args[]) throws Exception
{
BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
//Look, I'm explicitly sending Shutdown, too!
String sentence = "Shutdown";
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9877);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
}
}
I would be happy if both would work on the same computer for now, but after this String issue is fixed, I need to get more PCs involved. Tried about every solution suggested in other similar questions on stackoverflow and anything google listed on the first three pages, nothing worked for me. Can you see something I can't?
The problem here is that you rely on the fixed size buffer byte[] ... = new byte[1024] to send and receive packets.
My advice is to send only the data you really need:
String sentence = "Shutdown";
byte[] sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9877);
... and create the String instance on the server side accordingly to the length obtained from the receivePacket.getLength() method:
String sentence = new String(receivePacket.getData(), 0, receivePacket.getLength());
See also public String(byte[] bytes, int offset, int length)
I am trying to set up a program that looks into UDP performance of packets and response times on my network. I have a client and server side class, for which I am specifying the packet size which to send pieces of text. For example, if I want to send a word of "Tester" in a 4 byte packet, it will send the "TEST" part but not reiterate through the rest of the word. I have tried to add in a while loop, but i don't think what I have is correct as it continuously sends the first 4 bytes. Does anyone know what sort of loop I need and where abouts it should be placed to get the outcome I am after? Code for the client is below. Many thanks in advance for any guidance.
//UDP Client
//Usage: java UDPClient [server addr] [server port]
import java.io.*;
import java.net.*;
public class UDPClient extends variable {
// static Integer portNo = 4444;
static Integer byteSize = 4;
public static void main(String[] args) throws Exception {
SocketForm form = new SocketForm();
long startTime; // Starting time of program, in milliseconds.
long endTime; // Time when computations are done, in milliseconds.
double time;
//get server address
String serverName = "localhost";
if (args.length >= 1)
serverName = args[0];
InetAddress serverIPAddress = InetAddress.getByName(serverName);
//get server port;
int serverPort = form.cliportNo;
if (args.length >= 2)
serverPort = Integer.parseInt(args[1]);
//create socket
DatagramSocket clientSocket = new DatagramSocket();
//get input from keybaord
byte[] sendData = new byte[byteSize];
BufferedReader inFromUser = new BufferedReader(new InputStreamReader (System.in));
while (true){ //incorrect as it is only repeating the first four bytes of the word typed in the console
String sentence = inFromUser.readLine();
startTime = System.currentTimeMillis();
sendData = sentence.getBytes();
//construct and send datagram;
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverIPAddress, serverPort);
clientSocket.send(sendPacket);
//receive datagram
byte[] receiveData = new byte [byteSize];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
//print output
String sentenceFromServer = new String(receivePacket.getData());
System.out.println("From Server:" + sentenceFromServer);
//close client socket
//clientSocket.close();
endTime = System.currentTimeMillis();
time = endTime - startTime;
//System.out.println("Time :" + time);
}
} //end of main
} //end of UDPClient
Do you mean like this?
private void sendChunked( String msg, int chunkSizeInBytes ) {
byte[] msgBytes = msg.getBytes();
for( int index = 0; index < msgBytes.length ; index += chunkSizeInBytes ) {
DatagramPacket packet = new DatagramPacket( msgBytes, index, Math.min( chunkSizeInBytes, msgBytes.length-index ));
send( packet ); // You know how that works ...
}
}
So I got this simple udp client/server code from the internet, and it works. However, when I enter something that is shorter than the thing I entered before it, I get the remaining characters left over. For example, if I first enter:
kitty
And then enter:
cat
The second print reads as:
catty
I've been looking at other people with similar problems and most of them seem to be solved by clearing the byte array. However, if I try to implement their answers, it doesn't fix my problem. What do I need to do, and (maybe more importantly) where in the code should it go? Here is the code:
Client:
import java.io.*;
import java.net.*;
class UDPClient
{
public static void main(String args[]) throws Exception
{
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = inFromUser.readLine();
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 20700);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
}
}
Server:
import java.io.*;
import java.net.*;
import java.util.*;
class UDPServer
{
public static void main(String args[]) throws Exception
{
DatagramSocket serverSocket = new DatagramSocket(21200);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
You don't need to clear the byte array, but you do need to take some notice of the length of the DatagramPacket after the receive, via the getLength() method; for example:
new String(packet.getData(), packet.getOffset(), packet.getLength());
You're doing that correctly in the server, but not in the client.
You also need to reset the length before calling receive(). Otherwise the DatagramPacket will keep shrinking to the length of the smallest packet received so far.
Hi i have a udp client server code that is not working i ask a general question "Is shane a good kid"both codes have no errors that come up but when i run the code it outputs
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
instead of letting the client greet the server. The flow should be Server initializes and waits for client--client greets server -- server asks the question -- client responds to question-- server tallies the yes no votes and displays weather or not the person is like =.
any advice on how to round the code out would be welcomed
hear is the server code
import java.net.*;
public class VotingServer {
//private static final int yes = 0;
private static int yes2;
public static void main(String[] args, int getrep) throws Exception{
// part 1: initialization
DatagramSocket serverSocket = new DatagramSocket(9876);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
InetAddress[] IPAddressList = new InetAddress[5];
int[] portList = new int[5];
// part 2: receive the greeting from clients
for (int i=0; i<1; i++) {
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String greeting = new String(receivePacket.getData());
System.out.println("From Client: " + greeting);
IPAddressList[i] = receivePacket.getAddress();
portList[i] = receivePacket.getPort();
} // for (i)
// part 3: broadcast the votiong question to all clients
String question = "is shane a good kid 1 for yes 0 no?\n";
for (int i=0; i<5; i++) {
sendData = question.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length);
serverSocket.send(sendPacket);
// part 5: receive the age of client (B)
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String ageStr = new String(receivePacket.getData());
yes2 = Integer.parseInt(ageStr);
IPAddressList[i] = receivePacket.getAddress();
portList[i] = receivePacket.getPort();
// part 6: compute the price (C)
double count= 0;
double no = 0;
if (yes2 >= 1 ) count = 1;
else
if (yes2 <= 0 ) no = 1;
// part 7: send the price to client
String rep = null;
String countStr = ""+count+"\n";
String noStr = ""+no+"\n";
if (no < count) rep = "Is a good kid";
else
if (no > count) rep = "is a bad kid";
System.out.println(" "+getrep);
sendData = countStr.getBytes();
sendData = noStr.getBytes();
sendData = rep.getBytes();
DatagramPacket sendPacket1 =
new DatagramPacket(sendData, sendData.length);
serverSocket.send(sendPacket1);
} // main()
}} // UDPServer
And here is the client code
import java.io.;
import java.net.;
public class ClientVoting {
public static void main(String[] args) throws Exception {
// part 1: initialization
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = inFromUser.readLine();
sendData = sentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
// part 2: receive the question from server
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String question = new String(receivePacket.getData());
System.out.println("From Server:" + question);
String yes2 = inFromUser.readLine();
sendData = yes2.getBytes();
DatagramPacket sendPacket1 =
new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket1);
// part 4: get the price from server
receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String rep = new String(receivePacket.getData());
System.out.println("the answer is " + rep);
// part 4: close the socket
clientSocket.close();
} // main()
} // class UDPClient
Thanks SPF
I get a NullPointException running your code in the Server-side... There are a few problems in the code itself. The first one is the index of the Array that you attempt to keep the instance of the Clients connection. At this point, you have only one...
for (int i=0; i<1; i++) {
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String greeting = new String(receivePacket.getData());
System.out.println("From Client: " + greeting);
IPAddressList[i] = receivePacket.getAddress();
portList[i] = receivePacket.getPort();
} // for (i)
However, at this point, your code is prone to NullPointException as you try to iterate over it 5 times...
String question = "is shane a good kid 1 for yes 0 no?\n";
for (int i=0; i<5; i++) {
sendData = question.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length);
serverSocket.send(sendPacket); <<<<---- NPE prone code line...
Here's the result of running the code...
From Client: hello
Exception in thread "main" java.lang.NullPointerException: null buffer || null address
at java.net.PlainDatagramSocketImpl.send(Native Method)
at java.net.DatagramSocket.send(DatagramSocket.java:629)
at com.vasoftware.sf.common.VotingServer.main(VotingServer.java:38)
Looking at this exception, I noticed that since your buffer would not be null, your address is the problem, since you create a new DatagramPacket without both the IP and the Port number of the client connection... You have to pass them to the DatagramPacket instance so that the server knows who is the client trying to communicate... A very simple/basic example of what you are trying to achieve is at http://systembash.com/content/a-simple-java-udp-server-and-udp-client/. Below is my initial fixing of the code... Your answers will still need some work on the buffer, which I will leave it as an exercise...
Here's a fixed code for Server that accepts only 1 client... I will leave the Multi-threaded stuff + the data handler for you as an exercise...
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Arrays;
public class VotingServer {
//private static final int yes = 0;
private static int yes2;
public static void main(String[] args) throws Exception {
// part 1: initialization
DatagramSocket serverSocket = new DatagramSocket(9876);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
InetAddress IPAddressList;
int portList = -1;
// part 2: receive the greeting from clients
System.out.println("Ready to receive connections at port " + serverSocket.getLocalPort());
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String greeting = new String(receivePacket.getData());
System.out.println("From Client: " + greeting);
IPAddressList = receivePacket.getAddress();
portList= receivePacket.getPort();
// part 3: broadcast the votiong question to all clients
String question = "is shane a good kid 1 for yes 0 no?\n";
sendData = question.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddressList, portList);
serverSocket.send(sendPacket);
// part 5: receive the age of client (B)
receiveData = new byte[1024];
receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String ageStr = new String(receivePacket.getData());
try {
yes2 = Integer.parseInt(ageStr); //<<<----- WILL NEVER GET THE VALUE... LEAVING IT AS AN EXERCISE....
} catch (NumberFormatException nfe) {
yes2 = 0;
}
receivePacket.getAddress();
receivePacket.getPort();
// part 6: compute the price (C)
double count= 0;
double no = 0;
if (yes2 >= 1 ) count = 1;
else
if (yes2 <= 0 ) no = 1;
// part 7: send the price to client
// ALSO FIXING SOME CODE HERE AS WELL....
String rep = null;
rep = no < count ? "Is a good kid" : "is a bad kid";
rep += " Server Count: " + count;
sendData = rep.getBytes();
DatagramPacket sendPacket1 = new DatagramPacket(sendData, sendData.length, IPAddressList, portList);
serverSocket.send(sendPacket1);
}
}
Here's the client-side:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class ClientVoting {
public static void main(String[] args) throws Exception {
// part 1: initialization
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
System.out.print("What's the question? ");
String sentence = inFromUser.readLine();
sendData = sentence.getBytes();
System.out.println("Attempting to connect the server at port " + 9876);
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
System.out.println("Initial greeting sent... Waiting for response...");
// part 2: receive the question from server
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String question = new String(receivePacket.getData());
System.out.println("From Server:" + question);
String yes2 = inFromUser.readLine();
sendData = yes2.getBytes();
DatagramPacket sendPacket1 =
new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket1);
// part 4: get the price from server
receiveData = new byte[1024];
receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String rep = new String(receivePacket.getData());
System.out.println("the answer is " + rep);
// part 4: close the socket
clientSocket.close();
} // main()
}
You MUST execute the server first, as it will listen to the socket open on port 9876. Then, you can connect to the server with the client.
###### Here's the output in the server-side... Just added a few details of what's going on...
Ready to receive connections at port 9876
From Client: Marcello
####### Here's the output of the client:
What's the question? Marcello
Attempting to connect the server at port 9876
Initial greeting sent... Waiting for response...
From Server:is shane a good kid 1 for yes 0 no?
the answer is is a bad kid Server Count: 0.0
As it seems that your requirement is to design a Server that can handle multiple clients and count on the number of votes, I would also recommend you to use a Multi-threaded version of the server by using different Threads to deal with each client in its own thread and update the value of the static counter (an example is a while(true) loop executing a new Runnable with an Executor here http://java-x.blogspot.com/2006/11/java-5-executors-threadpool.html). Think about creating a Runnable instance as described, and placing the server's code in the public void run() {} method implementation... I will leave this as an exercise for you as well...