Sending and receiving byte array in java - java

I'm having some trouble with my socket programming codes. I have a server tcp that receives the password from client, if it's true, the server will send a file back to client to save, else server will send a byte array with the length is 0.
Then the client will receive the byte array and get the length to compare with 0, if byte length = 0, the client will print out "Wrong password", else it will tell you to enter the file name.
The big problem is the server sent byte array with length = 0 when password is wrong, but client receive byte array with length = 1. I do not know how to solve it....:(
Here is my TCPServer code:
import java.io.*;
import java.net.*;
import java.util.Scanner;
class ServerTCP{
public static void main (String[] args){
try{
ServerSocket ss = new ServerSocket(2018);
System.out.println("\n(*) Server Socket has been created!");
while(true){
Socket s = ss.accept();
InputStream is = s.getInputStream();
OutputStream os = s.getOutputStream();
PrintWriter pw = new PrintWriter(os);
Scanner sc = new Scanner(is);
//Receive information from client
String mail = sc.nextLine();
String pass = sc.nextLine();
System.out.println("Password is: " + pass);
if(matkhau.equals("passtcp")){
String filegui = "D:/filename.pdf";
FileInputStream f = new FileInputStream(filegui);
int lenf = f.available();
byte b2[] = new byte[lenf];
f.read(b2);
f.close();
os.write(b2);
}
else{
byte b[] = new byte[1];
int lenb = 0;
os.write(b);
}
}
}catch(IOException e){
System.out.println("\n(!)An error occured while creating socket!");
}
}
}
Here is my client code
import java.net.*;
import java.io.*;
import java.util.Scanner;
class UdpTcpTest{
public static void main (String[] args){
//String matkhau = new String();
Scanner k = new Scanner(System.in);
try{
//Enter TCP Server's ip
System.out.print("Enter TCP Server's ip: ");
String ip1 = k.nextLine();
//Tao socket
Socket s = new Socket(ip1, 2018);
InputStream is = s.getInputStream();
OutputStream os = s.getOutputStream();
PrintWriter pw = new PrintWriter(os);
String mail = "yourmail#test.com";
String password = "matkhaune";
//send mail and password to server
pw.println(mail); pw.flush();
pw.println(password); pw.flush();
//receive information
byte brecv[] = new byte[60000];
int lenfile = is.read(brecv);
System.out.println("Length = " + lenfile);
if(lenfile <= 1){
System.out.println("Wrong password! Length = " + lenfile);
}
else{
//Save file
System.out.print("Enter file name to save: ");
String filenamed = k.nextLine();
FileOutputStream f = new FileOutputStream(filenamed);
f.write(brecv, 0, lenfile);
f.close();
System.out.println("Saving Scuccess!");
s.close();
}
}catch(IOException e){
System.out.println("Error while excuting!");
}
}
}

I'm having some trouble with my socket programming codes. I have a server tcp that receives the password from client, if it's true, the server will send a file back to client to save, else server will send a byte array with the length is 0.
Impossible.
Then the client will receive the byte array and get the length to compare with 0, if byte length = 0, the client will print out "Wrong password", else it will tell you to enter the file name.
Impossible. You will have to redesign your protocol. You can't send a byte array of zero length over TCP. The minimum is one byte.
The big problem is the server sent byte array with length = 0 when password is wrong
No it didn't. It sent a byte array with length = 1:
byte b[] = new byte[1]; // Here is your byte array of length 1
int lenb = 0; // This is unused. Delete.
os.write(b); // Here you are sending the entire byte array
but client receive byte array with length = 1.
That is correct.
I do not know how to solve it....:(
There is nothing here to solve. Your code is working as designed. You just need to adjust your client to test for a 1-byte receive instead of an impossible zero-byte receive:
int lenfile = is.read(brecv);
System.out.println("Length = " + lenfile);
if(lenfile == 1){

Related

Cant send the data from my "sender.java" to my "receiver.java". (Java Socket Programming)

I am having issues with my two java programs communicating with each other. The problem is that the "receiver.java" program that acts as the server cannot run / start or receive data from the "sender.java" program. The sender program works and runs fine though on port :4444. I am getting Java socket connection error so it has something to do with connection.
FINAL UPDATE EDIT*****: It works fine now, I fixed the first problem by changing the ports to match. (4444). And I passed the receiver to connect through (IP,4444) NOT (localhost,4444) so I ran "sender.java" on my local IP address which is 127...*:4444 and "receiver.java" on (localhost:4444) and they connected and the receiver received the checksum data I inputed. Thanks all!
Check_Sum_Sender.java
// Java code for Checksum_Sender
package checksum_sender;
import java.io.*;
import java.net.*;
import java.util.*;
public class Checksum_Sender
{
// Setting maximum data length
private int MAX = 100;
// initialize socket and I/O streams
private Socket socket = null;
private ServerSocket servsock = null;
private DataInputStream dis = null;
private DataOutputStream dos = null;
public Checksum_Sender(int port) throws IOException
{
servsock = new ServerSocket(port);
// Used to block until a client connects to the server
socket = servsock.accept();
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
while (true)
{
int i, l, sum = 0, nob;
Scanner sc = new Scanner(System.in);
System.out.println("Enter data length");
l = sc.nextInt();
// Array to hold the data being entered
int data[] = new int[MAX];
// Array to hold the complement of each data
int c_data[] = new int[MAX];
System.out.println("Enter data to send");
for (i = 0; i < l; i++)
{
data[i] = sc.nextInt();
// Complementing the entered data
// Here we find the number of bits required to represent
// the data, like say 8 requires 1000, i.e 4 bits
nob = (int)(Math.floor(Math.log(data[i]) / Math.log(2))) + 1;
// Here we do a XOR of the data with the number 2^n -1,
// where n is the nob calculated in previous step
c_data[i] = ((1 << nob) - 1) ^ data[i];
// Adding the complemented data and storing in sum
sum += c_data[i];
}
// The sum(i.e checksum) is also sent along with the data
data[i] = sum;
l += 1;
System.out.println("Checksum Calculated is : " + sum);
System.out.println("Data being sent along with Checkum.....");
// Sends the data length to receiver
dos.writeInt(l);
// Sends the data one by one to receiver
for (int j = 0; j < l; j++)
dos.writeInt(data[j]);
// Displaying appropriate message depending on feedback received
if (dis.readUTF().equals("success"))
{
System.out.println("Thanks for the feedback!! Message received Successfully!");
break;
}
else if (dis.readUTF().equals("failure"))
{
System.out.println("Message was not received successfully!");
break;
}
}
// Closing all connections
dis.close();
dos.close();
socket.close();
}
// Driver Method
public static void main(String args[]) throws IOException
{
Checksum_Sender cs = new Checksum_Sender(4444);
}
}
Check_Sum_Receiver.java
// Java code for Checksum_Receiver
package checksum_sender;
import java.net.*;
import java.io.*;
import java.util.*;
public class Checksum_Receiver {
// Initialize socket and I/O streams
private Socket s = null;
private DataInputStream dis = null;
private DataOutputStream dos = null;
// Constructor to put ip address and port
public Checksum_Receiver(InetAddress ip,int port)throws IOException
{
// Opens a socket for connection
s = new Socket(ip,port);
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
while (true)
{ Scanner sc = new Scanner(System.in);
int i, l, nob, sum = 0, chk_sum;
// Reads the data length sent by sender
l = dis.readInt();
// Initializes the arrays based on data length received
int c_data[] = new int[l];
int data[] = new int[l];
System.out.println("Data received (alond with checksum) is");
for(i = 0; i< data.length; i++)
{
// Reading the data being sent one by one
data[i] = dis.readInt();
System.out.println(data[i]);
// Complementing the data being received
nob = (int)(Math.floor(Math.log(data[i]) / Math.log(2))) + 1;
c_data[i] = ((1 << nob) - 1) ^ data[i];
// Adding the complemented data
sum += c_data[i];
}
System.out.println("Sum(in ones complement) is : "+sum);
// Complementing the sum
nob = (int)(Math.floor(Math.log(sum) / Math.log(2))) + 1;
sum = ((1 << nob) - 1) ^ sum;
System.out.println("Calculated Checksum is : "+sum);
// Checking whether final result is 0 or something else
// and sending feedback accordingly
if(sum == 0)
{
dos.writeUTF("success");
break;
}
else
{
dos.writeUTF("failure");
break;
}
}
// Closing all connections
dis.close();
dos.close();
s.close();
}
// Driver Method
public static void main(String args[])throws IOException
{
// Getting ip address on which the receiver is running
// Here, it is "localhost"
InetAddress ip = InetAddress.getLocalHost();
Checksum_Receiver cr = new Checksum_Receiver(ip,4444);
}
}
For anyone who reads this and finds this answer helpful to them. These were the fixes for my problems:
1: Make sure the port numbers match on both sender and receiver program. (sender:port=receiver:port)
2: Use your local IP address for the sender (127.0.0.1:port) and use (localhost:port) for the receiver! OR vice versa.
3: Then for data input start the sender program first but don't input anything yet, then start the receiver so the data-stream can be connected. Then input data as you like!

Writing bytes to file from multiple packets

i am working on algorithm that will receive data and i want to write them to the file.
First packet that i receive is packet containing fileName.
Second packet is containing sizeOfPacket.
then i have to calculate number of Packets that i receive.
But my actual problem starts when i want to receive next packets and write these packets to the file byte by byte.
I tried it in many ways but every time the resulting file is just 1kb large but actual image is 72kb large.
I have to read from the packets from 4th byte because first 4 bytes are storing position of packet in file.
Size of every packet is 1024B
public void run(int port) throws IOException {
try {
byte[] receiveData = new byte[1024];
DatagramSocket serverSocket = new DatagramSocket(port);
System.out.printf("Listening on udp:%s:%d%n",
InetAddress.getLocalHost().getHostAddress(), port);
DatagramPacket receivePacket = new DatagramPacket(
receiveData,
SIZE_OF_PACKET
);
//first packet with name of file
serverSocket.receive(receivePacket);
String fileName = utils.getFileName(receivePacket);
//System.out.println(fileName);
//System.out.println(fileName.length());
//second packet with size of whole data()
serverSocket.receive(receivePacket);
int sizeOfFile = utils.BytesToInt(receivePacket);
//get number of packets that are needed
int numOfPackets = utils.getNumOfPackets(sizeOfFile);
//System.out.println(sizeOfFile);
//System.out.println(numOfPackets);
//output stream for file "test.jpg"
FileOutputStream fos = new FileOutputStream("test.jpg");
//loop over for the number of Packets
for(int i = 0; i < numOfPackets - 1; i++) {
serverSocket.receive(receivePacket);
receiveData = receivePacket.getData();
//byte byte after byte and write it to the file
// start at index 3 bcs first byte is packet number
for(int a = 3; a < SIZE_OF_PACKET - 1;a++) {
Byte nextByte = receiveData[a];
if(nextByte != 0) fos.write(nextByte);
}
}
fos.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}

Sending binary file over TCP from Python server to Java client

I am trying to send binary files over TCP. The server is written in Python and the client in Java.
Server:
import socket;
TCP_IP = '127.0.0.1'
TCP_PORT = 5001;
BUFFER_SIZE = 1024;
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
s.listen(1)
except:
"Can not bind server on port: "+ str(TCP_PORT) +"\n";
while 1:
print("Wait for connections!!!\n");
conn, addr = s.accept();
print("Receive a new connection!!!\n");
# presentation of client
data = conn.recv(BUFFER_SIZE);
if not data:
conn.close();
print("Lost connection!!!");
continue;
# respond to client
conn.sendall("Hello 1\n");
# receive new request
data = conn.recv(BUFFER_SIZE);
if not data:
continue;
conn.sendall("OK\n");
f = open('testImage.jpg', "rb");
dataRaw = f.read();
f.close();
fileSize = len(dataRaw); #sys.getsizeof(dataRaw);
# send file size
conn.send(str(fileSize) + "\n");
conn.send(dataRaw);
conn.sendall("OK\n");
Client
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class mainTestReceiveFile
{
public static void main(String[] args) throws Exception
{
String usr2ConnectDefault = "127.0.0.1";
int port2ConnectDefault = 5001;
Socket socket;
BufferedReader in;
PrintWriter out;
socket = new Socket(usr2ConnectDefault, port2ConnectDefault);
System.out.println("Connected to server...sending echo string");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(),true);
// say hello to server
out.println("Hello");
// read hello from server
String readString = in.readLine();
System.out.println(readString);
out.println("ReadFile");
// verify if request is OK
readString = in.readLine();
if(readString.compareToIgnoreCase("OK") == 0)
System.out.println("Receive new file!!!");
else
{
socket.close();
return;
}
// get size of file
readString = in.readLine();
int sizeOfFile = Integer.parseInt(readString);
//InputStream is = socket.getInputStream();
byte[] fileData = new byte[sizeOfFile];
for(int i = 0; i < sizeOfFile; i++)
{
fileData[i] = (byte)in.read();
}
// save file to disk
FileOutputStream fos = new FileOutputStream("fileImage.jpg");
try
{
fos.write(fileData);
}
finally {
fos.close();
}
// verify if request is OK
readString = in.readLine();
if(readString.compareToIgnoreCase("OK") == 0)
System.out.println("New file received!!!");
else
{
socket.close();
return;
}
socket.close();
}
}
I am trying to send for example one image. In the client side, the image received has the same size (file size and number of pixels) but the data is corrupted.

Multicast a file to a group of users

I have a problem to send a file to a group of users. Users could receive the file was sent from server but the file would not be saved if it is less than 8kb.
Here is the code:
MulticastSocketServer
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class MulticastSocketServer{
public static void main(String[] args) {
String fileName;
String address = "235.0.0.1";
int port = 2222;
Scanner in = new Scanner(System.in);
System.out.print("Please enter file name : ");
fileName = in.next();
try (DatagramSocket serverSocket = new DatagramSocket()) {
InetAddress addr = InetAddress.getByName(address);
BufferedReader br = new BufferedReader(new FileReader(fileName + ".txt"));
DatagramPacket fn = new DatagramPacket(fileName.getBytes(),fileName.getBytes().length, addr, port);
serverSocket.send(fn);
DatagramPacket msgPacket = null;
String txt = "";
while((txt = br.readLine())!=null){
msgPacket = new DatagramPacket(txt.getBytes(),txt.getBytes().length, addr, port);
serverSocket.send(msgPacket);
System.out.println(txt);
}
}catch (IOException ex) {ex.printStackTrace();}
}
}
MulticastSocketClient
import java.io.*;
import java.net.*;
public class MulticastSocketClient {
public static void main(String[] args) throws UnknownHostException {
int port = 2222;
String address = "235.0.0.1";
InetAddress addr = InetAddress.getByName(address);
byte[] buf = new byte[64];
byte[] buf2 = null ;
try (MulticastSocket clientSocket = new MulticastSocket(port)){
clientSocket.joinGroup(addr);
DatagramPacket fn = new DatagramPacket(buf, buf.length);
clientSocket.receive(fn);
String name = new String(buf, 0, buf.length);
String fileName = name.trim();
try(PrintWriter pw = new PrintWriter(new FileWriter(fileName+"2.txt"))){
while (true) {
buf2 = new byte [1024];
DatagramPacket msgPacket = new DatagramPacket(buf2, buf2.length);
clientSocket.receive(msgPacket);
String msg = new String(buf2,0,buf2.length);
String txt = msg.trim();
pw.println(txt);
System.out.println(txt);
}
}catch(FileNotFoundException ex){ex.printStackTrace();}
} catch (IOException ex) {ex.printStackTrace();}
}
}
You're never exiting the while (true) loop, because you don't have any mechanism for transmitting end of stream, so you're never closing the PrintWriter, so it isn't flushing its final buffer, so any file < 4096 chars won't get flushed at all, so it will be zero length.
However your code has much worse problems that this. You are assuming:
the filename fits into 1024 characters
every line of the input file fits into 1024 bytes
the filename is received first
all the content packets are received
all the content packets are received in order
all the content packets are received exactly once
the length of every datagram is 1024
the data is text, not binary, and can be converted losslessly to a String
You're using UDP. That means that most of these assumptions are invalid.

How to read all of Inputstream in Server Socket JAVA

I am using Java.net at one of my project.
and I wrote a App Server that gets inputStream from a client.
But some times my (buffered)InputStream can not get all of OutputStream that client sent to my server.
How can I write a wait or some thing like that, that my InputStream gets all of the OutputStream of client?
(My InputStream is not a String)
private Socket clientSocket;
private ServerSocket server;
private BufferedOutputStream outputS;
private BufferedInputStream inputS;
private InputStream inBS;
private OutputStream outBS;
server = new ServerSocket(30501, 100);
clientSocket = server.accept();
public void getStreamFromClient() {
try {
outBS = clientSocket.getOutputStream();
outputS = new BufferedOutputStream( outBS);
outputS.flush();
inBS = clientSocket.getInputStream();
inputS = new BufferedInputStream( inBS );
} catch (Exception e) {
e.printStackTrace();
}
}
Thanks.
The problem you have is related to TCP streaming nature.
The fact that you sent 100 Bytes (for example) from the server doesn't mean you will read 100 Bytes in the client the first time you read. Maybe the bytes sent from the server arrive in several TCP segments to the client.
You need to implement a loop in which you read until the whole message was received.
Let me provide an example with DataInputStream instead of BufferedinputStream. Something very simple to give you just an example.
Let's suppose you know beforehand the server is to send 100 Bytes of data.
In client you need to write:
byte[] messageByte = new byte[1000];
boolean end = false;
String dataString = "";
try
{
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
while(!end)
{
int bytesRead = in.read(messageByte);
dataString += new String(messageByte, 0, bytesRead);
if (dataString.length == 100)
{
end = true;
}
}
System.out.println("MESSAGE: " + dataString);
}
catch (Exception e)
{
e.printStackTrace();
}
Now, typically the data size sent by one node (the server here) is not known beforehand. Then you need to define your own small protocol for the communication between server and client (or any two nodes) communicating with TCP.
The most common and simple is to define TLV: Type, Length, Value. So you define that every message sent form server to client comes with:
1 Byte indicating type (For example, it could also be 2 or whatever).
1 Byte (or whatever) for length of message
N Bytes for the value (N is indicated in length).
So you know you have to receive a minimum of 2 Bytes and with the second Byte you know how many following Bytes you need to read.
This is just a suggestion of a possible protocol. You could also get rid of "Type".
So it would be something like:
byte[] messageByte = new byte[1000];
boolean end = false;
String dataString = "";
try
{
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
int bytesRead = 0;
messageByte[0] = in.readByte();
messageByte[1] = in.readByte();
int bytesToRead = messageByte[1];
while(!end)
{
bytesRead = in.read(messageByte);
dataString += new String(messageByte, 0, bytesRead);
if (dataString.length == bytesToRead )
{
end = true;
}
}
System.out.println("MESSAGE: " + dataString);
}
catch (Exception e)
{
e.printStackTrace();
}
The following code compiles and looks better. It assumes the first two bytes providing the length arrive in binary format, in network endianship (big endian). No focus on different encoding types for the rest of the message.
import java.nio.ByteBuffer;
import java.io.DataInputStream;
import java.net.ServerSocket;
import java.net.Socket;
class Test
{
public static void main(String[] args)
{
byte[] messageByte = new byte[1000];
boolean end = false;
String dataString = "";
try
{
Socket clientSocket;
ServerSocket server;
server = new ServerSocket(30501, 100);
clientSocket = server.accept();
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
int bytesRead = 0;
messageByte[0] = in.readByte();
messageByte[1] = in.readByte();
ByteBuffer byteBuffer = ByteBuffer.wrap(messageByte, 0, 2);
int bytesToRead = byteBuffer.getShort();
System.out.println("About to read " + bytesToRead + " octets");
//The following code shows in detail how to read from a TCP socket
while(!end)
{
bytesRead = in.read(messageByte);
dataString += new String(messageByte, 0, bytesRead);
if (dataString.length() == bytesToRead )
{
end = true;
}
}
//All the code in the loop can be replaced by these two lines
//in.readFully(messageByte, 0, bytesToRead);
//dataString = new String(messageByte, 0, bytesToRead);
System.out.println("MESSAGE: " + dataString);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
You can read your BufferedInputStream like this. It will read data till it reaches end of stream which is indicated by -1.
inputS = new BufferedInputStream(inBS);
byte[] buffer = new byte[1024]; //If you handle larger data use a bigger buffer size
int read;
while((read = inputS.read(buffer)) != -1) {
System.out.println(read);
// Your code to handle the data
}
int c;
String raw = "";
do {
c = inputstream.read();
raw+=(char)c;
} while(inputstream.available()>0);
InputStream.available() shows the available bytes only after one byte is read, hence do .. while

Categories

Resources