i'm stuck with a small problem that i can't solve .... i need to create an app in java that connects to irc server and have the ability to transfer a file to another client with in a specific channel. So i tried this below code and it doesnt work out,my problem is in making the socket to transfer the file. and at this given code i make the irc client to send you a file when you send a message "sendFile" to it, but it doesnt send the file named "any.txt" to the sender of the message. so what can i possibly do to transfer the file to the other client ??? .... and almost forgot ... when you try to send the command "sendFile" to the irc client, you must have a nickname "mer" without the "".
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.File;
import java.io.FileInputStream;
import java.net.InetAddress;
public class MainTest {
private static String nickUse;
public static void main(String args[]) throws Exception{
// The server to connect to and our details.
File fileIn = new File("any.txt");
String server = "localhost";
String nick = "testJava";
String login = "anyName";
// The channel which the bot will join.
String channel = "#here";
// Connect directly to the IRC server.
ServerSocket serverSoc = new ServerSocket(0);
Socket socket = new Socket(server, 6667);
InetAddress intetAdd = socket.getInetAddress();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream( )));
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream( )));
// Log on to the server.
writer.write("NICK " + nick + "\r\n");
writer.write("USER " + login + " 8 * : This is a channel\r\n");
writer.flush( );
// Read lines from the server until it tells us we have connected.
String line = null;
while ((line = reader.readLine( )) != null) {
if (line.indexOf("004") >= 0) {
// We are now logged in.
break;
}
else if (line.indexOf("433") >= 0) {
System.out.println("Nickname is already in use.");
return;
}
}
// Join the channel.
writer.write("JOIN " + channel + "\r\n");
writer.flush( );
// Keep reading lines from the server.
while ((line = reader.readLine( )) != null) {
if (line.startsWith("PING ")) {
// We must respond to PINGs to avoid being disconnected.
writer.write("PONG " + line.substring(5) + "\r\n");
writer.flush();
System.out.println("THis is the line recieved when server sends a ping verification "+line);
}
else {
// Print the raw line received by the bot.
System.out.println(line);
if(line.contains(":") && line.contains("!")){
int positionOfIni = line.indexOf(":");
int lastOf = line.indexOf("!");
String nickComm = line.substring(positionOfIni+1,lastOf);
if(!nickComm.equalsIgnoreCase("mer")){
nickUse = nickComm;
}
}
if(nickUse!=null && line.endsWith(nickUse) == false){
int messagePo = line.lastIndexOf(":");
System.out.printf("%s %s %s\n",nickUse,"Says:",line.substring(messagePo+1));
nickUse = null;
}
if(line.endsWith("sendFile")){
byte[] add = intetAdd.getAddress();
writer.write("PRIVMSG " + "mer" +" :\u0001"+ "DCC SEND "+fileIn.getName()+" "+ipToLong(add)+" "+serverSoc.getLocalPort()+" "+fileIn.length()+"\u0001");
writer.flush();
Socket serSoc = serverSoc.accept();
serSoc.setSoTimeout(30000);
serverSoc.close();
BufferedOutputStream output = new BufferedOutputStream(serSoc.getOutputStream());
BufferedInputStream input = new BufferedInputStream(serSoc.getInputStream());
BufferedInputStream finput = new BufferedInputStream(new FileInputStream(fileIn));
byte[] outBuffer = new byte[1024];
byte[] inBuffer = new byte[4];
int bytesRead = 0;
while ((bytesRead = finput.read(outBuffer, 0, outBuffer.length)) != -1) {
output.write(outBuffer, 0, bytesRead);
output.flush();
input.read(inBuffer, 0, inBuffer.length);
Thread.sleep(4);
}
}
}
}
}
public static long ipToLong(byte[] address) {
if (address.length != 4) {
throw new IllegalArgumentException("byte array must be of length 4");
}
long ipNum = 0;
long multiplier = 1;
for (int i = 3; i >= 0; i--) {
int byteVal = (address[i] + 256) % 256;
ipNum += byteVal*multiplier;
multiplier *= 256;
}
System.out.println(ipNum);
return ipNum;
}
}
i just conclude the answer of having not to transfer with the help of IRC server. but instead i just create it's own server, that is capable of receiving files (Encrypted).
Related
I am having trouble sending data between a UDP Server and Client, I am trying to ,send an array of strings to the client from the server. The loop that I am using will hang up and stop reading the data from the server. If i pick a small number for the loop everything is okay it works but if I try to transmit the whole string it will stop half way and the client freezes up. Here is the server it reads a file and then sends the data to the client using a loop.
```
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class UDPServer1
{
public static void main(String[] args) throws Exception
{
int portNumber=9999;
UDPConnection com1 = null;
InetAddress ipAddress = InetAddress.getLocalHost();
Message MS1 = new Message();
char x = 0;
int m = 12, c=0;
double q;
int percent=20;
String[] message = new String[255];
String m1;
x = (char)m;
m1 = x + ""; //turn next page character into string
double rand = Math.random();
//String ACK="";
System.out.println("Enter the percentage of packet losses will happen in the transmission: ");
//percent = MS1.getInt();
DatagramSocket ds=new DatagramSocket(portNumber);
File infile = new File("COSC635_P2_DataSent.txt");
Scanner sc = new Scanner(infile);
// we just need to use next page as delimiter
sc.useDelimiter(m1);
while(sc.hasNext() ) //get data packets
{
message[c] = sc.next()+m1;
c++;
}
System.out.println("UDP server Started ");
byte[] data = new byte[6500];
DatagramPacket receivedFrame = new DatagramPacket(data, data.length);
ds.receive(receivedFrame);
String ACK = new String(receivedFrame.getData(),0, receivedFrame.getLength());
//str = message[80];
//receiveData(ds);
//com1.setPort(receivedFrame.getPort());
portNumber = receivedFrame.getPort();
byte[] frame;
//dp1;
//System.out.println("Dp port is " + dp.getPort());
int i = 0;
while( i<=c-1) //error control goes here
{
//frame = (message[i].trim() ).getBytes();
//ipAddress = InetAddress.getLocalHost();
//DatagramPacket sendFrame= new DatagramPacket(frame, frame.length, ipAddress, receivedFrame.getPort());
sendData(ds, message[i].trim()+ACK+ " port number is " + portNumber, InetAddress.getLocalHost(), portNumber);
//ds.receive(receivedFrame);
//ACK = receiveData(ds);
//simulate lost packets
//rand = Math.random();
//q = rand*100;
//if(percent < (int)q)
//ds.send(sendFrame);
i++;
}
//frame = ("End of File").getBytes();
//ipAddress = InetAddress.getLocalHost();
//sendFrame= new DatagramPacket(frame, frame.length, ipAddress, receivedFrame.getPort());
//ds.send(sendFrame);
ds.close();
}
static String receiveData(DatagramSocket socket) throws IOException
{
byte buffer[];
buffer = new byte[6500];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String received = new String(packet.getData(), 1, packet.getLength() - 1).trim();
System.out.println(received);
return received;
}
static void sendData(DatagramSocket ds, String data, InetAddress ipAddress, int portNumber) throws IOException
{
byte[] frame = null;
frame = (data.trim() ).getBytes();
DatagramPacket dp1= new DatagramPacket(frame, frame.length, ipAddress, portNumber);
//simulate lost packets
//rand = Math.random();
//q = rand*100;
//if(percent < (int)q)
ds.send(dp1);
}
}
```
Here is the code for the client.
```
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.lang.Math;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
public class UDPClient
{
public static void main(String[] args) throws Exception
{
DatagramSocket dsocket = new DatagramSocket();
String fileContent ="";
InetAddress ipAddress = InetAddress.getLocalHost();
int socketNumber=9999;
byte[] ACK = null;
FileWriter fileWriter = new FileWriter("COSC635_P2_DataRecieved.txt");
System.out.println("UDP Client Started");
String mess = "";
Message m1;
//send frames
//Frame is the string
ACK = (" ").getBytes();
DatagramPacket dp= new DatagramPacket(ACK, ACK.length, ipAddress, socketNumber);
dsocket.send(dp);
byte[] data = new byte[6500];
String str = "";
DatagramPacket dp1 = new DatagramPacket(data, data.length);
dsocket.receive(dp1);
str = new String(dp1.getData());
int i =0;
while( i<70) //error control needs to go here
{
//ds.receive(dp1);
//str = new String(dp1.getData(), 1, dp1.getLength() - 1).trim();
mess = receiveData(dsocket);
//mess = mess + " i is " + i;
System.out.println( mess.trim());
System.out.println( "inside loop");
//fileContent = fileContent + mess;
i++;
sendData(dsocket, "Packet Received " + i + " ", ipAddress, i);
}
//
//System.out.println(fileContent);
System.out.println("outside loop");
fileWriter.write(fileContent);
fileWriter.close();
dsocket.close();
System.out.println("data socket closed");
}
static String receiveData(DatagramSocket socket) throws IOException
{
byte buffer[];
buffer = new byte[6500];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String received = new String(packet.getData(), 1, packet.getLength() - 1).trim();
System.out.println(received);
return received;
}
static void sendData(DatagramSocket ds, String data, InetAddress ipAddress, int portNumber) throws IOException
{
byte[] frame = null;
frame = (data.trim() ).getBytes();
DatagramPacket dp1= new DatagramPacket(frame, frame.length, ipAddress, portNumber);
ds.send(dp1);
}
}
```
So the the server program consists of the following code:
import java.io. * ;
import java.net. * ;
import java.util. * ;
public class TimeServer {
public static void main(String[] args) {
try {
//Create sockets
ServerSocket ss = new ServerSocket(60000);
Socket rs = ss.accept();
//create streams
BufferedInputStream bs = new BufferedInputStream(rs.getInputStream());
InputStreamReader isr = new InputStreamReader(bs);
BufferedOutputStream bos = new BufferedOutputStream(rs.getOutputStream());
PrintWriter pw = new PrintWriter(bos);
//set timeout
rs.setSoTimeout(20000);
int c = 0;
StringBuilder sb = new StringBuilder();
//while loop reads in a character until a period (includes period)
while (((char) c != '.')) {
c = isr.read();
//append each char to a string builder
sb.append((char) c);
}
//convert stringbuilder to string
String str = sb.substring(0);
//If string equals "time." returns time else error message
if (str.compareTo("time.") == 0) {
Date now = new Date();
pw.print("time is: " + now.toString());
pw.flush();
}
else {
pw.print("Invalid syntax: connection closed");
pw.flush();
}
//close socket
rs.close();
//close serversocket
ss.close();
} catch(IOException i) {
System.out.println(i.getMessage());
}
}
}
The code for the client is:
import java.io. * ;
import java.net. * ;
import java.util. * ;
public class TimeClient {
public static void main(String[] args) {
try {
//create socket
Socket sock = new Socket("localhost", 60000);
//create streams
BufferedInputStream bis = new BufferedInputStream(sock.getInputStream());
InputStreamReader isr = new InputStreamReader(bis);
BufferedOutputStream bos = new BufferedOutputStream(sock.getOutputStream());
PrintWriter pw = new PrintWriter(bos);
//set timeout
sock.setSoTimeout(20000);
//write argument to stream, argument should be "time." to recieve time
pw.write(args[0]);
pw.flush();
int c = 0;
StringBuilder sb = new StringBuilder();
//while loop reads each character into stringbuilder
while ((c != -1)) {
c = isr.read();
sb.append((char) c);
}
//stringbuilder converted to string and printed
String str = sb.substring(0);
System.out.println(str);
//socket closed
sock.close();
} catch(IOException i) {
System.out.println(i.getMessage());
}
}
}
The problem is that if I run each program in a separate cmd.exe, they do not communicate despite using localhost as the IP address. I can't seem to find the logical error in the code which causes this and wondered if anyone could help?
The problem is that you are using a BufferedOutputStream and you close the socket immediately after writing on the PrintWriter. What you have written remains in the buffer and the socket is closed before anything has been sent to the client.
You need to flush before closing in order to force the content of the buffer to be sent:
...
//close socket
pw.flush();
rs.close();
...
TimeClient contains a minor error: you loop receiving until you get a -1 which is correct, but you append that -1 to the StringBuilder which is wrong. It should be:
//while loop reads each character into stringbuilder
while(true){
c = isr.read();
if (c == -1) { break; }
sb.append((char) c);
}
But this should never prevent the text to be displayed...
There are two files (client file, server file) in this program that are supposed to be able to send and receive messages (utf-8 strings) to each other. Each file has a thread (one thread for client, one thread for server)
The client and the server connect on localhost with a port number (it should be the same port number when typing on the command prompt / mac terminal window)
However, the server is supposed to only send messages to all the other clients after receiving a message from a client. In other words, if a client sends a message to the server, the server cannot send that message back to the same client--it can only send messages to the different clients.
Another way to say it: Once a client is connected, it can send messages to the server. It will also receive from the server all messages sent from the other connected clients (not the messages sent from itself).
At runtime, there is supposed to be only one server (mac terminal / command prompt windows) but there can be multiple/infinite number of clients (mac terminal / command prompt windows)
Screenshot of error (server side):
Screenshot of error (client side):
Code of ChatServer.java:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatServer
{
private static Socket socket;
public static void main(String args[])
{
Thread ChatServer1 = new Thread ()
{
public void run ()
{
System.out.println("Server thread is now running");
try
{
int port_number1 = 0;
int numberOfClients = 0;
boolean KeepRunning = true;
if(args.length>0)
{
port_number1 = Integer.valueOf(args[0]);
}
System.out.println("Waiting for connections on port " + port_number1);
try
{
ServerSocket serverSocket = new ServerSocket(port_number1);
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println( "Listening for connections on port: " + ( port_number1 ) );
while(KeepRunning)
{
ServerSocket serverSocket = new ServerSocket(port_number1);
//create a list of clients
ArrayList<String> ListOfClients = new ArrayList<String>();
//connect to client
socket = serverSocket.accept();
//add new client to the list, is this the right way to add a new client? or should it be in a for loop or something?
ListOfClients.add("new client");
numberOfClients += 1;
System.out.println("A client has connected. Waiting for message...");
ListOfClients.add("new client" + numberOfClients);
//reading encoded utf-8 message from client, decoding from utf-8 format
String MessageFromClientEncodedUTF8 = "";
BufferedReader BufReader1 = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
String MessageFromClientDecodedFromUTF8 = BufReader1.readLine();
byte[] bytes = MessageFromClientEncodedUTF8.getBytes("UTF-8");
String MessageFromClientDecodedUTF8 = new String(bytes, "UTF-8");
//relaying message to every other client besides the one it was from
for (int i = 0; i < ListOfClients.size(); i++)
{
if(ListOfClients.get(i)!="new client")
{
String newmessage = null;
String returnMessage = newmessage;
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage + "\n");
System.out.println("Message sent to client: "+returnMessage);
bw.flush();
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (socket != null)
{
socket.close ();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
};
ChatServer1.start();
}
}
Code of ChatClient.java:
import java.io.*;
import java.net.*;
import java.util.*;
import static java.nio.charset.StandardCharsets.*;
public class ChatClient
{
private static Socket Socket;
static int numberOfClients = 0;
public static void main(String args[])
{
//If I wanted to create multiple clients, would this code go here? OR should the new thread creation be outside the while(true) loop?
while (true)
{
String host = "localhost";
int numberOfClients = 0;
Thread ChatClient1 = new Thread ()
{
public void run()
{
try
{
//Client begins, gets port number, listens, connects, prints out messages from other clients
int port = 0;
int port_1number1 = 0;
int numberofmessages = 0;
String[] messagessentbyotherclients = null;
System.out.println("Try block begins..");
System.out.println("Chat client is running");
String port_number1= args[0];
System.out.println("Port number is: " + port_number1);
if(args.length>0)
{
port = Integer.valueOf(port_number1);
}
System.out.println("Listening for connections..");
System.out.println( "Listening on port: " + port_number1 );
Socket.connect(null);
System.out.println("Client has connected to the server");
for(int i = 0; i < numberOfClients; i++)
{
System.out.println(messagessentbyotherclients);
}
//client creates new message from standard input
OutputStream os = Socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
//creating message to send from standard input
String newmessage = "";
try
{
// input the message from standard input encoded in UTF-8 string format
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line = "";
System.out.println( "Standard input (press enter then control D when finished): " );
while( (line= input.readLine()) != null )
{
newmessage += line + " ";
input=null;
}
}
catch ( Exception e )
{
System.out.println( e.getMessage() );
}
//Sending the message to server
String sendMessage = newmessage;
bw.write(sendMessage + "\n");
bw.flush();
System.out.println("Message sent to server: "+sendMessage);
}
catch (IOException e)
{
e.printStackTrace();
}
}
};
ChatClient1.start();
}
}
}
These two errors have been covered many times and I've heard that the answer is to put the socket in a loop, which it already is in (while loop).
My question is: Is there a way to locate the errors before running it? Whenever I compile the program I don't get any errors in eclipse, but when I run it in the command prompt window / mac terminal, it does tell me that something is wrong. Or perhaps there's a line of code that I'm overlooking?
ServerSocket serverSocket = new ServerSocket(port_number1);
Place it once, before the while loop.
Please help, connection to server has been made but the server willl not respond to any requests. Just trying to get the time and date working by sending the server "1". P.s i know i should not have all of the cases of 1-7 but i just want to get the date ad time working before worrying about any others
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Date;
import java.util.Scanner;
/**
*
* #author samdo
*/
public class SocketProgrammingSamD {
/**
* #param args the command line arguments
*/
private static Scanner in;
public static void main(String[] args) throws IOException {
System.out.println("Samuel Donini");
System.out.println(" ");
System.out.println("Project 1");
System.out.println(" ");
System.out.println(" ");
//new Driver().execute(args);//Creates an instance of the Driver class and Calls the Driver.execute method
in = new Scanner(System.in);
System.out.println("(Client) Enter Server Ip to Connect to(Empty will give localhost):");
String ip = in.nextLine();
System.out.println("(Client) Enter your server port no:");
int port = in.nextInt();
if (ip == null || ip.length() == 0) {
ip = "localhost";
}
System.out.println("Connecting to " + ip + ":" + port);
// for taking input from client
// InputStream inputStream = connectionSocket.getInputStream();
// Try to connect to port and the IP address given on the command line.
try (Socket socket = new Socket(ip, port)) {
// for taking input from client
// InputStream inputStream = connectionSocket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(System.in);
BufferedReader inputFromClient = new BufferedReader(inputStreamReader);
// for giving output to the client.
OutputStream outputStream = socket.getOutputStream();
// output to client, to send data to the server
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
// get output from server
InputStream serverInputStream = socket.getInputStream();
InputStreamReader inputStreamReaderFromServer = new InputStreamReader(
serverInputStream);
BufferedReader bufferReader = new BufferedReader(
inputStreamReaderFromServer);
//System.out.println("(Client) Give input:");
System.out.printf("Menu Options:\t\t\tCommands\n");
System.out.printf("-------------\t\t\t--------\n");
System.out.printf(" * 1 current Date & Time:\t1\n");
System.out.printf(" * 2 uptime: \t\t 2\n");
System.out.printf(" * 3 memory use: \t\t3\n");
System.out.printf(" * 4 Netstat: \t\t 4\n");
System.out.printf(" * 5 current users: \t\t5\n");
System.out.printf(" * 6 disk usage: \t\t6\n");
System.out.printf(" * 7 Quit: \t\t\t7\n\n");
String readingLineFromUser = inputFromClient.readLine();
// sending data to server
dataOutputStream.writeBytes(readingLineFromUser + "\n");
String getStringFromServer = bufferReader.readLine();
System.out.println("Got input from server (in client):" + getStringFromServer);
//attempts to get System Time
System.out.println("Requesting system time");
System.out.println("1");
//System.out.write("Server Date" + (new Date()).toString() + "\n");
System.out.println("Response from the server:\n");
// Read lines from the server and print them until "ServerDone" on
// a line by itself is encountered.
String answer;
while ((answer = inputFromClient.readLine()) != null && !answer.equals("ServerDone")) {
System.out.println(answer);
}
return;
}
}
}
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
public class Server {
private static ServerSocket severSocket;
private static Scanner in;
public static void main(String[] args) throws IOException {
in = new Scanner(System.in);
System.out.println("(Server) Enter your server port no:");
int port = in.nextInt();
System.out.println("Server Estabilsh Connection On Localhost or own ip with port : " + port);
severSocket = new ServerSocket(port);
System.out.println("Now you can run your client app.");
while (true) {
Socket connectionSocketListens = severSocket.accept();//Listens for a connection to be made to this socket and accepts it.
System.out.println("Accepted Client connection");
// for taking input from client
InputStream inputStream = connectionSocketListens.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(
inputStream);
BufferedReader inputFromClient = new BufferedReader(
inputStreamReader);
// for giving output to the client.
OutputStream outputStream = connectionSocketListens.getOutputStream();
// output to client, to send data to the server
DataOutputStream dataOutputStream = new DataOutputStream(
outputStream);
// get output from server
String readingLineFromClientSocket = inputFromClient.readLine();
// sending data to client
String modified = doOperation(readingLineFromClientSocket);
// send data to client
dataOutputStream.writeBytes(modified + "\n");
// Read the request from the client! *** input = inputFromClient
String answer = inputFromClient.readLine();
System.out.println("Request from client "+answer);
Process cmdProc;
cmdProc = null;
// Execute the appropriate command.
if (answer.charAt(0) == '1') {
System.out.println("Responding to date and time request from the client ");
cmdProc = Runtime.getRuntime().exec("date");//MUST ADD TIME
}
if (answer.charAt(0) == '2') {
System.out.println("Responding to uptime request from the client ");
cmdProc = Runtime.getRuntime().exec("date");//MUST CHANGE
}
if (answer.charAt(0) == '3') {
System.out.println("Responding to memory use request from the client ");
cmdProc = Runtime.getRuntime().exec("date");
}
if (answer.charAt(0) == '4') {
System.out.println("Responding to Netstat request from the client ");
cmdProc = Runtime.getRuntime().exec("date");
}
if (answer.charAt(0) == '5') {
System.out.println("Responding to current users request from the client ");
cmdProc = Runtime.getRuntime().exec("date");
}
if (answer.charAt(0) == '6') {
System.out.println("Responding to disk usage request from the client ");
cmdProc = Runtime.getRuntime().exec("date");
}
if (answer.charAt(0) == '7') {
System.out.println("Responding to Quit request from the client ");
cmdProc = Runtime.getRuntime().exec("date");
}
else {
System.out.println("Unknown request ");
//need a socket.close or Server.close(); or something like that
return;
}
//Read the result of the commands and sent the result to the client one line at a time
// followed by the line "ServerDone"
BufferedReader cmdin = new BufferedReader(new InputStreamReader(cmdProc.getInputStream()));
String cmdans;
while ((cmdans = cmdin.readLine()) != null) {
System.out.println(cmdans);
}
System.out.println("ServerDone");
return;
}
}
private static String doOperation(String readingLineFromClientSocket) {
String[] array = readingLineFromClientSocket.split(" ");
StringBuilder strBuilder = new StringBuilder(array.length);
for (int i = array.length - 1; i >= 0; i--) {
String s = charReverse(array[i]);
strBuilder.append(s);
strBuilder.append(" ");
}
return strBuilder.toString();
}
private static String charReverse(String str) {
return new StringBuilder(str).reverse().toString();
}
}
I have a working version after making the following changes:
I changed this code in the Server class:
String answer = inputFromClient.readLine();
to
//String answer = inputFromClient.readLine();
String answer = modified;
System.out.println("Request from client "+answer);
Also all the lines like the following (apart from the first):
if (answer.charAt(0) == '2')
need to be
else if (answer.charAt(0) == '2')
and - on Windows at least - the following line:
cmdProc = Runtime.getRuntime().exec("date");
needs to be
cmdProc = Runtime.getRuntime().exec("cmd /c date /T");
This line:
while ((answer = inputFromClient.readLine()) != null && !answer.equals("ServerDone")) {
should be:
while ((answer = bufferReader.readLine()) != null && !answer.equals("ServerDone")) {
And after this line:
System.out.println(cmdans);
you need:
dataOutputStream.writeBytes(cmdans + "\n");
I'm trying to send a DatagramPacket, and then must wait for an Acknowlegment from sever, so that I know if I have to resend the same packet or send the next one..
I'm using for that the same socket on the client, to send the datapacket and to receive the acknowlegment (ack), and same in the server's side, another socket that is used to receive the datapacket and then to send the acknowledgment to the client..
The 1st problem is that the client is sending the datapacket, the server is receiving it, then sends the acknowledgment to client, but the client blocks on receiving the Acknowledgment-packet.
I'm making some System.out.println to identify where is the problem, but I couldnt find any solution to this problem.
The 2nd problem is that the Server is still always receiving data, and dont wait for the client to send something, i checked that because i got that lines(like "got packet with length xxx" "ack sent with ackNr yyy" ..." printed on the server's side, all the time although the client is blocking after sending the 1st packet, because it's waiting for the acknowledgment that is not received!
Here is the CLIENT's code:
package blatt7;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.zip.CRC32;
public class FileSender {
String zielRechner;
String filePath;
InetAddress host;
File file;
FileInputStream fis;
int readLength;
int sequenceNr = 0;
int receivedSeqNr = 1;
static int port = 7777;
int packetNr = 0;
byte[] packet = new byte[1216];
byte[] data = new byte[1200];
byte[] header = new byte[16];
byte[] readLengthByte = new byte[4];
byte[] sequenceNrByte = new byte[4];
byte[] checksumByte = new byte[8];
byte[] ackBuffer = new byte[4];
CRC32 checksumCalculator = new CRC32();
DatagramPacket dp;
DatagramPacket ackPacket;
DatagramSocket sendSocket = null;
//DatagramSocket ackSocket = null;
static boolean ackReceived = true;
public FileSender(String zielRechner, String filePath) throws UnknownHostException, FileNotFoundException {
this.zielRechner = zielRechner;
this.filePath = filePath;
this.host = InetAddress.getByName(zielRechner);
this.file = new File(filePath);
fis = new FileInputStream(file);
}
public void sendFile() throws IOException {
while((readLength = fis.read(data)) != -1) {
if (sequenceNr == 1)
sequenceNr = 0;
else
sequenceNr = 1;
readLengthByte = intToBytes(readLength);
sequenceNrByte = intToBytes(sequenceNr);
for(int i=0; i<4; i++) {
header[8+i] = readLengthByte[i];
}
for(int i=0; i<4; i++) {
header[12+i] =sequenceNrByte[i];
}
int j=0;
for (int i=0; i<packet.length; i++) {
if (i < header.length)
packet[i] = header[i];
else {
packet[i] = data[j];
j++;
}
}
checksumCalculator.reset();
checksumCalculator.update(packet,8,8+readLength);
checksumByte = longToBytes(checksumCalculator.getValue());
for(int i=0; i < 8; i++) {
packet[i] = checksumByte[i];
}
dp = new DatagramPacket(packet, packet.length, host, port);
while(receivedSeqNr == sequenceNr && ackReceived) {
try {
ackReceived = false;
sendSocket = new DatagramSocket();
sendSocket.send(dp);
sendSocket.setSoTimeout(10000);
packetNr++;
System.out.println("Packet sent with seqNr: " + sequenceNr + " and length: " + bytesToInt(readLengthByte, 0) + " - PACKET NR: " + packetNr);
ackPacket = new DatagramPacket(ackBuffer, ackBuffer.length);
System.out.println("TEST!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
sendSocket.receive(ackPacket);
System.out.println("Receiving ACK!!");
ackReceived = true;
ackBuffer = ackPacket.getData();
receivedSeqNr = bytesToInt(ackBuffer,0);
System.out.println("got SequenceNr with receivedSeq-Nr: " + receivedSeqNr);
} catch (SocketTimeoutException e) {
e.printStackTrace();
break;
}
}
}
fis.close();
System.out.println("Transfer Completed Successfully!");
sendSocket.close();
}
public static byte[] longToBytes(long value) {
ByteBuffer buffer = ByteBuffer.allocate(8);
buffer.putLong(value);
return buffer.array();
}
public static long bytesToLong(byte[] bytes, int index) {
ByteBuffer buffer = ByteBuffer.allocate(8);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getLong(index);
}
public static byte[] intToBytes(int value) {
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.putInt(value);
return buffer.array();
}
public static int bytesToInt(byte[] bytes, int index) {
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.put(bytes);
buffer.flip();//need flip
return buffer.getInt(index);
}
public static void main(String[] args) throws IOException,ClassNotFoundException {
FileSender sender = new FileSender("localhost", "C:/Users/Kb/Desktop/Deepophile - Psychedelic Sessions.wav");
sender.sendFile();
}
}
and here is the SERVER's code:
package blatt7;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.zip.CRC32;
public class FileReceiver {
byte[] incomingBuffer;
DatagramPacket incomingPacket;
DatagramSocket receiveSocket;
DatagramPacket ackPacket;
int packetCounter = 0;
int dataLength;
int receivedSeqNr;
long calculatedChecksum;
long receivedChecksum;
CRC32 checksumCalculator = new CRC32();
byte[] dataLengthByte = new byte[4];
byte[] receivedSeqNrByte = new byte[4];
byte[] receivedChecksumByte = new byte[8];
byte[] ackArray;
public FileReceiver() throws SocketException {
incomingBuffer = new byte[1500];
incomingPacket = new DatagramPacket(incomingBuffer, incomingBuffer.length);
}
public void receive() throws IOException {
receiveSocket = new DatagramSocket(FileSender.port);
receiveSocket.setSoTimeout(10000);
System.out.println("Server socket created. Waiting for incoming data...");
while(true && FileSender.ackReceived)
{
receiveSocket.receive(incomingPacket);
packetCounter++;
for (int i=0; i <4; i++) {
dataLengthByte[i] = incomingBuffer[8+i];
}
dataLength = FileSender.bytesToInt(dataLengthByte,0);
checksumCalculator.reset();
checksumCalculator.update(incomingBuffer, 8, dataLength+8);
calculatedChecksum = checksumCalculator.getValue();
for (int i=0; i <4; i++) {
receivedSeqNrByte[i] = incomingBuffer[12+i];
}
receivedSeqNr = FileSender.bytesToInt(receivedSeqNrByte,0);
for (int i=0; i <8; i++) {
receivedChecksumByte[i] = incomingBuffer[i];
}
long receivedChecksum = FileSender.bytesToLong(receivedChecksumByte,0);
System.out.println("Got packet with checksum: " + receivedChecksum);
System.out.println("Server-calculated checksum: " + calculatedChecksum);
System.out.println("Got packet with seqNr: " + receivedSeqNr + " and length: " + dataLength);
if (calculatedChecksum != receivedChecksum) {
sendACK(receivedSeqNr);
System.out.println("Packet have erros(s)! It must be sent another time!");
}
else if(calculatedChecksum == receivedChecksum && receivedSeqNr == 1) {
sendACK(0);
System.out.println("SeqNr '0' sent");
}
else if (calculatedChecksum == receivedChecksum && receivedSeqNr == 0) {
sendACK(1);
System.out.println("SeqNr '1' sent");
}
}
}
public void sendACK(int seqNum) throws IOException {
byte[] ackArray = FileSender.intToBytes(seqNum);
ackPacket = new DatagramPacket(ackArray, ackArray.length, InetAddress.getByName("localhost"), FileSender.port);
receiveSocket.send(ackPacket);
}
public static void main(String[] args) throws IOException,ClassNotFoundException {
FileReceiver receiver = new FileReceiver();
receiver.receive();
}
}
You can try to execute it to see where the problem is...
So PLEASE if you have ANY idea how can I solve this problem, let me know!
Thankyou verymuch!
Can anyone tell me where to find the received file? or how should I change my code so that I choose where to save it??
Yes it is possible. Your problem is that you have the target address:port wrong when sending the ACK datagram. You should get the target address:port from the received DatagramPacket, or simpler still just reuse that datagram with different data as the ACK datagram.
How server can send to client using own port? You are sending ACK from server to client on Server's port, you should get client's UDP port from received packet and send data to that port.
EDIT
Change in Server in SendACK method to:
ackPacket = new DatagramPacket(ackArray, ackArray.length, InetAddress.getByName("localhost"), incomingPacket.getPort());
And now analyze code by running.