Socket Failing to finish sending 4Byte Packets - java

This is more a follow up to a previous question asked earlier however I have modified my original code now, to be able to send a file Instead of text) via a UDP socket with a specific packet size. The program runs perfectly if I specify a 1, 2 or 4 byte packet, however if I try for anything larger, such as a 8, 16 etc, the program grinds to a halt. No exception is thrown in the console, however Netbeans shows a tiny warning symbol in the bottom right hand corner and shows the following.
java.lang.IllegalArgumentException: Contents must be presorted - added value 42318 is less than preceding value 42320
at org.netbeans.core.output2.IntList.add(IntList.java:76)
at org.netbeans.core.output2.AbstractLines.addTabAt(AbstractLines.java:1122)
at org.netbeans.core.output2.OutWriter.doWrite(OutWriter.java:452)
at org.netbeans.core.output2.OutWriter.write(OutWriter.java:506)
at java.io.PrintWriter.write(PrintWriter.java:456)
at java.io.PrintWriter.write(PrintWriter.java:473)
at org.apache.tools.ant.module.bridge.impl.ForkedJavaOverride$Copier.maybeFlush(ForkedJavaOverride.java:350)
at org.apache.tools.ant.module.bridge.impl.ForkedJavaOverride$Copier.access$000(ForkedJavaOverride.java:251)
at org.apache.tools.ant.module.bridge.impl.ForkedJavaOverride$Copier$1.run(ForkedJavaOverride.java:271)
at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1432)
[catch] at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2044)
Is this error thrown because of the UDP Packets being received out of order by any chance? Is there a way to ignore this? I can tell the program has ceased as the string of "The End" does not appear. Does anyone know why this may be? My code for my client socket is attached below (its a bit of a long one and lots of comments for my own sanity). Many thanks in advance for any guidance.
public class UDPClient extends variable {
// static Integer portNo = 4444;
static Integer byteSize = 16;
public static void main(String[] args) throws Exception { //taken out main from here
SocketForm form = new SocketForm();
File file=null;
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){
//String sentence = inFromUser.readLine();
startTime = System.currentTimeMillis();
//sendData = sentence.getBytes();
String fileName = "/Users/Andrew/Desktop/pic.jpg";
File f = new File(fileName);
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
System.out.println("Total file size to read in bytes is : " + fis.available());
} catch (IOException e) {}
Path path = Paths.get("/Users/Andrew/Desktop/pic.jpg");
//byte[] data = Fles.readAllBytes(path);
sendData = Files.readAllBytes(path);
try {
for( int index = 0; index < sendData.length ; index += byteSize ) {
DatagramPacket packet = new DatagramPacket( sendData, index, Math.min( byteSize, sendData.length-index ), serverIPAddress, serverPort);
clientSocket.send(packet);
//DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverIPAddress, serverPort);
//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);
}
System.out.println("The End");
}
catch (Exception e) {}
//close client socket
//clientSocket.close();
endTime = System.currentTimeMillis();
time = endTime - startTime;
System.out.println("Time :" + time);
// }
} //end of main
} //end of UDPClient

Solved. Was running 7.3 of Netbeans. It is a known issue in 7.3 and has been addressed in the latest revision of 7.4. Solution : Update to Netbeans 7.4. Now purring like a cat. Thanks to all those who tried to help with this!

Related

Java Multicast Socket doesn't receive anything on Windows

I need to send and receive in multicast.
This is my Sender:
public static void main(String[] args) {
MulticastSocket socket = null;
try {
socket = new MulticastSocket(3575);
int n = 1;
while (n <= 100) {
byte[] buf = new byte[256];
// non aspetta la richiesta
String dString = new Date().toString();
buf = dString.getBytes();
// invia il messaggio in broadcast
InetAddress group = InetAddress.getByName("230.0.0.1");
DatagramPacket packet = new DatagramPacket(buf, buf.length, group, 3575);
socket.send(packet);
System.out.println ("Broadcasting: "+dString);
Thread.sleep(1000);
n++;
}
socket.close();
}catch(Exception e) { e.printStackTrace(); socket.close();}
}//main
This is my Receiver:
public static void main(String[] args) throws IOException {
MulticastSocket socket = new MulticastSocket(3575);
InetAddress group = InetAddress.getByName("230.0.0.1");
socket.joinGroup(group);
DatagramPacket packet;
for (int i = 0; i < 100; i++) {
byte[] buf = new byte[256];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData()).trim();
System.out.println("Time: " + received);
}
socket.leaveGroup(group);
socket.close();
}//main
When I run them, the Receiver does not receive anything.
I tried on two different PC ( both with Windows) with AntiVirus and firewall disabled. I also tried with different LAN: my router, my phone hotspot.
It does not work neither on local machine.
How can I solve the problem?
Thanks
I compiled and ran your code on my laptop, with the sender and receiver on the same machine. It works. (Fedora 26 Linux, Java 1.8.0_171)
It seems that the problem is something to do with your networking, not the application code. So, since this not a programming problem, I think you would be better off asking this Question on the ServerFault site ... where they specialize in networking, etcetera.

Sending much files through socket Java c#

I am trying to send set of files through socket C# and Java application, I am not able to recieve all files. The server application closes connections, I think, because the server always closes connection after sending the file without making sure that the client app received the file.
Here is the C# client code:
public static void connectWithRemoteServer(string strIp, string strMessage, out
string strResult)
{
strResult = "";
TcpClient tcpClient = new TcpClient();
tcpClient.Connect(strIp, 1593);
NetworkStream networkStream = tcpClient.GetStream();
StreamReader sr = new StreamReader(networkStream);
if (strMessage.Substring(0,1).Equals("s"))
{
byte[] byteBuffer = Encoding.ASCII.GetBytes(strMessage);
networkStream.Write(byteBuffer, 0, byteBuffer.Length);
strResult = sr.ReadLine();
}
else if (strMessage.Substring(0, 1).Equals("f"))
{
byte[] byteBuffer = Encoding.ASCII.GetBytes(strMessage);
networkStream.Write(byteBuffer, 0, byteBuffer.Length);
int length = int.Parse(sr.ReadLine());
byte[] buffer = new byte[length];
networkStream.Read(buffer, 0, (int)length);
string var = strMessage.Substring(1);
//write to file
BinaryWriter bWrite = new BinaryWriter(File.Open(var, FileMode.Create));
bWrite.Write(buffer);
bWrite.Flush();
bWrite.Close();
strResult = "ok";
}
tcpClient.Close();
}
}
foreach (string strFilePath in lst)
{
Utilities.connectWithRemoteServer("192.168.0.167", "f" + strFilePath, out str);
}
Java Server app
while(true)
{
String listeFiles = "";
ServerSocket serverSocket = new ServerSocket(1593);
System.out.println("Server started and waiting for request..");
Socket socket = serverSocket.accept();
System.out.println("Connection accepted from " + socket);
// this is to send to the client application
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
// this is to receive from the client application
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
byte[] bytearray = new byte[in.available()];// recived byte from the
// client application
in.read(bytearray, 0, bytearray.length);// read recieved byte from
String strRecieved = new String(bytearray);// get the received string
System.out.println(strRecieved);
//strRecieved = strRecieved.trim();
if(strRecieved.substring(0,1).equals("s"))
{
List<String> lstFiles = GetFiles.getListFilesPath("./testData");
for (String str : lstFiles) {
listeFiles = str + "+" + listeFiles;
}
String listFilesToSend = listeFiles.substring(0, listeFiles.length() - 1);
out.println(listFilesToSend);
System.out.println("List Files Send ");
serverSocket.close();
socket.close();
}
else if (strRecieved.substring(0,1).equals("f"))
{
File file = new File(strRecieved.substring(1));
// // send file length
out.println(file.length());
// read file to buffer
byte[] buffer = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.read(buffer, 0, buffer.length);
// // send file
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write(buffer);
bos.flush();
serverSocket.close();
socket.close();
}
}
}
How to make sure the file has been received successfully before send the next file Issue
unable to write data to the transport connection an existing connection was forcibly closed
Any help would be appreciated.
Thank you .

How to properly compare string values received from datagram packets?

I'm making a simple client server program. When the client sends the string "start", I want the server to start executing some code. Right now, I have the client sending a datagram packet with the message "start", the server gets the byte buffer from the packet, turns it into a string, and then compares that string value with the string literal "start". Obviously I'm doing something wrong because my code never enters the for loop of if(sentence.equals(start){ System.out.println("ok");}
My code:
public static void main(String args[]) throws IOException{
byte[] receiveData;
byte[] sendData;
DatagramSocket serverSocket = new DatagramSocket(2014);
while(true){
receiveData = new byte[15];
DatagramPacket frame = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(frame);
InetAddress IPaddress = frame.getAddress();
System.out.println("INET " + IPaddress);
byte[] data;
int port = frame.getPort();
System.out.println("port " + port);
String sentence = new String(frame.getData());
String start = new String("start");
System.out.println("RECEIVED FROM CLIENT: " + sentence);
if(sentence.equals(start)){
System.out.println("ok");
}
}
}
Make the following change.
String sentence = new String(frame.getData(), 0, frame.getLength());

Udp how to get integer from the server?

i shall implement a UDP-based client/server application and im new in the world of Java. The Server implements a simple request-acknowledge protocol upon the UDP protocol. For a received string identifier (command) with optional parameters the server returns a specified result. For example "thread" returns a random integer number between 1 and 5 and length returns a random integer number between 5 and 25.
The questions is did i do the implementation right and how can i fix my problem (length nr is always between 1 and 5). I think my problem is that in the server class the if statements are not checked. Is there some other way to send a comand to a server i tried here to do it with sending strings then trying to check it with if statements?
and thats my code (Server):
public class server {
public static void main(String[] args) throws IOException, InterruptedException {
DatagramSocket skt;
try {
skt = new DatagramSocket(1252);
byte [] buffer = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
skt.receive(request);
String arrayMsg = new String(request.getData());
System.out.println(arrayMsg);
//check if the client asks for threadnr
if(arrayMsg.equals("thread")){
int threadnumber = (int) (Math.random()*5)+1;
String threadnum = Integer.toString(threadnumber);
byte [] b = threadnum.getBytes();
DatagramPacket reply = new DatagramPacket(b, b.length, request.getAddress(), request.getPort());
skt.send(reply);;}
//check if the client asks for lengthnr
else if(arrayMsg.equals("length")){
int lengthnumber = (int) (Math.random()*25)+5;
String lengthnum = Integer.toString(lengthnumber);
byte [] b = lengthnum.getBytes();
DatagramPacket reply = new DatagramPacket(b, b.length,request.getAddress(), request.getPort());
skt.send(reply);}
}}
catch (SocketException e) {
System.out.println("UDP Port 9876 is occupied.");
System.exit(1);
}}}
thats my Client:
public class client {
public static void main(String[] args) throws UnknownHostException, IOException {
DatagramSocket skt = new DatagramSocket();
InetAddress host = InetAddress.getByName("localhost");
int serverSocket = 1252;
byte [] senddata = new byte [1000];
byte [] getdata = new byte[1000];
//thread send request
String th = "thread";
senddata = th.getBytes();
DatagramPacket requestth = new DatagramPacket(senddata, senddata.length, host, serverSocket);
skt.send(requestth);
//thread get reply
DatagramPacket replyth = new DatagramPacket ( getdata, getdata.length);
skt.receive(replyth);
String arrayth = new String(replyth.getData());
int threadnr=Integer.parseInt(arrayth.trim()); //convert thread string to int and trim it (whitespace)
System.out.println("Thread received " + threadnr);
//length send request
String lg = "length";
senddata = lg.getBytes();
DatagramPacket requestlg = new DatagramPacket(senddata, senddata.length, host, serverSocket);
skt.send(requestlg);
//length get reply
DatagramPacket replylg = new DatagramPacket ( getdata, getdata.length);
skt.receive(replylg);
String arraylg = new String(replyth.getData());
int lengthnr=Integer.parseInt(arraylg.trim()); //convert thread string to int and trim it (whitespace)
System.out.println("Length received " + lengthnr);
skt.close();
And all i get is something like this:
Thread received 3
Length received 1
(Length should be between 5 and 25 and in my case its never bigger then 5)
The code parses the response from the first message instead of from the last, so you get the random 1-5. I suggest using better names for the variables and you'll spot the problem quicker.

Stop and wait UDP server

I am trying to program a Java stop-and-wait UDP server and I have gotten this far with the server but I am not sure where to go next. I want the client to send a message to the server, set a timeout, wait for a response, if it doesn't get one, then resend the packet, if it does then increment the sequence no. until it get to ten and keep send and receiving messages with the server.
I have gotten this far, how do I fix this ? :
import java.io.*;
import java.net.*;
public class Client {
public static void main(String args[]) throws Exception {
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
InetAddress IPAddress = null;
try {
IPAddress = InetAddress.getByName("localhost");
} catch (UnknownHostException exception) {
System.err.println(exception);
}
//Create a datagram socket object
DatagramSocket clientSocket = new DatagramSocket();
while(true) {
String sequenceNo = "0";
sendData = sequenceNo.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 6789);
clientSocket.send(sendPacket);
clientSocket.setSoTimeout(1);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
if(clientSocket.receive(receivePacket)==null)
{
clientSocet.send(sendPacket);
}else { //message sent and acknowledgement received
sequenceNo++; //increment sequence no.
//Create a new datagram packet to get the response
String modifiedSentence = sequenceNo;
//Print the data on the screen
System.out.println("From : " + modifiedSentence);
//Close the socket
if(sequenceNo >= 10 ) {
clientSocket.close();
}
}}}}
The first problem I can see (apart from the mistyped variable names which will stop your code compiling) is your socket timeout: if the socket timeout expires, the receive function will throw a SocketTimeoutException which your code does not handle. receive does not return a value, so the result can't be compared with null. Instead, you need to do something like this:
try {
clientSocket.receive(receivePacket);
sequenceNo++;
... // rest of the success path
} catch (SocketTimeoutException ex) {
clientSocket.send(sendPacket);
}

Categories