SocketException when reading file with BufferedInputStream - sockets

I'm writing a TCP Server and Client, in which the client will send the file and the server will save it. My send/save function is as following:
Server
public void saveFile2(Socket clientSocket) throws IOException
{
BufferedInputStream bis = new BufferedInputStream(clientSocket.getInputStream());
DataInputStream dis = new DataInputStream(bis);
String fileName = dis.readUTF();
File file = new File(fileName);
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int byteCount;
byte[] buffer = new byte[4096];
while ((byteCount = bis.read(buffer, 0, buffer.length)) > 0)
{
System.out.println("Test byteCount = "+byteCount);
bos.write(buffer, 0, byteCount);
break;
}
System.out.println("Saved file"+file.getName());
bos.close();
dis.close();
}
Client
public void sendFile2(String xmlpath) throws IOException, InterruptedException
{
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
DataOutputStream dos = new DataOutputStream(bos);
File file = new File(xmlpath);
System.out.println("Sending File : " + file.getName());
dos.writeUTF(file.getName());
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
int bytesCount;
byte[] buffer = new byte[4096];
System.out.println("Sending file to server.");
while ((bytesCount = fis.read(buffer)) > 0 )
{
System.out.println(bytesCount);
bos.write(buffer, 0, bytesCount);
}
System.out.println("Finished sending.");
bis.close();
dos.flush();
}
Notice that I have added a break; command into the while loop of Server and the program work perfectly. But when I exclude it, I get this exception:
Test byteCount = 394
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:209)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at xml.xmlServer.saveFile2(xmlServer.java:72)
at xml.xmlServer.run(xmlServer.java:31)
This only occur when I include BufferedInputStream and BufferedOutputStream in my code. Can somebody help me explain what causes this exception ?

You're reading the filename but you aren't sending the filename. You're missing a writeUTF() call in the sender.
You also need to close the socket in the sender, or the DataOutputStream.
bos.write(buffer, 0, bytesCount);
Really this should be
dos.write(buffer, 0, bytesCount);

Related

Why receiveData in UDP Socket contains "square" char?

When i run Server and Client, type a string form Client to Server, Server response that string and "square" char.
I have consulted many codes but the result is still the same........................................................................................................................................................................................................................................................................................................
My Server :
public class serverUDP {
public static void main(String args[]) throws Exception {
DatagramSocket serverSocket = new DatagramSocket(9876);
while(true) {
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[2048];
// receive packet
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
String sentence_to_client = sentence+ " (server accpeted!)";
// send packet
sendData = sentence_to_client.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
My Client :
public class clientUDP {
public static void main(String args[]) throws Exception {
DatagramSocket clientSocket = new DatagramSocket(6789);
InetAddress IPAddress = InetAddress.getByName("localhost");
while(true){
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[2048];
// input
BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));
String sentence = inFromUser.readLine();
// send packet
sendData = sentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
// receive packet
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modified_Sentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modified_Sentence);
if(sentence.compareTo("quit") == 0)
break;
}
clientSocket.close();
}
}
Result: String + "square" char

TCP Server Not Receiving Message From TCP Client (Java)

It seems like the server is not receiving the message sent from the client as it should. From my understanding the client is writing to the socket outputstream. And the server is reading from the socket inputstream. Please help.
Server Code:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TCPServer {
static final int DEFAULT_PORTNUMBER = 1236;
public static void main(String[] args){
int portnumber;
if(args.length >= 1){
portnumber = Integer.parseInt(args[0]);
}else{
portnumber = DEFAULT_PORTNUMBER;
}
//Setting a server socket and a possible client socket
ServerSocket server = null;
Socket client;
try{
server = new ServerSocket(portnumber);
} catch (IOException e){
e.printStackTrace();
}
while(true){
try{
System.out.println("Waiting for client...");
client = server.accept();
System.out.println("Client accepted... ");
//Read data form the client
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
while(!br.ready()){
System.out.println("No message from client");
}
String msgFromClient = br.readLine();
//System.out.println("Message received from client = " + msgFromClient);
//Send Response
if(msgFromClient != null && !msgFromClient.equalsIgnoreCase("bye")){
OutputStream clientOut = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOut, true);
String ansMsg = "Hello, " + msgFromClient;
pw.println(ansMsg);
}
if(msgFromClient != null && msgFromClient.equalsIgnoreCase("Bye")){
server.close();
client.close();
break;
}
} catch(IOException e) {
e.printStackTrace();
}
//New thread for client
/*new ServerThread(client).start();
System.out.println("Client connection accepted... ");*/
}
}
}
Client Code:
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
public class TCPClient {
static final int DEFAULT_PORTNUMBER = 1236;
public static void main(String args[]){
Socket client = null;
int portnumber;
//Default port number if not specified as an argument
if(args.length >= 1){
portnumber = Integer.parseInt(args[0]);
}else{
portnumber = DEFAULT_PORTNUMBER;
}
try {
String msg = "";
//Creating a client socket
client = new Socket(InetAddress.getLocalHost(), portnumber);
System.out.println("Client socket is created: " + client);
//Creating an output stream for the client socket
OutputStream clientOUt = client.getOutputStream();
PrintWriter pw = new PrintWriter(clientOUt, true);
//Creating an input stream for the client socket
InputStream clientIn = client.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(clientIn));
//Creating a buffered reader for standard input System.in
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter your name. Type Bye to exit.");
//Read data from standard input and write to output stream
msg = stdIn.readLine().trim();
pw.print(msg);
while(!br.ready()){
//System.out.println("No Input From Server");
}
//Read data from input stream of client socket
System.out.println("Message returned from the server = " + br.readLine());
pw.close();
br.close();
client.close();
//Stop operation
if (msg.equalsIgnoreCase("Bye")) {
System.exit(0);
} else {
}
} catch (IOException e) {
System.out.println("I/O error " + e);
}
}
}
Note: I did disable firewall but that did not help.
Found the answer PrintWriter or any other output stream in Java do not know "\r\n". It describes how printwriter doesn't flush properly with printwriter.print() but rather only works when you use printwriter.println().

How to fix corrupt byte[]-s in win socket

I have two win socket apps, server and client. The server app is at my virtual and client at host machine and the communication is OK. I am sending a ISO file (700MB) through that socket and I came across the error that received bytes are corrupt. When my file come to virtual machine, it has the original size, but the content is not OK. At the client side, I am using this code:
public class ProgramClient
{
public static void StartClient()
{
// Data buffer for incoming data.
byte[] msg;
try
{
IPAddress ipAd = IPAddress.Parse("192.168.137.71");
IPEndPoint remoteEP = new IPEndPoint(ipAd, 1234);
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sender.Connect(remoteEP);
Console.WriteLine("Client connected to {0}", sender.RemoteEndPoint.ToString());
Console.WriteLine("Sending file...");
msg = GetBinaryFile(#"C:\TCPIP\test_big.iso");
byte[] msgLengthBytes = BitConverter.GetBytes(msg.Length-3);
int msgLength = BitConverter.ToInt32(msgLengthBytes, 0);
Console.WriteLine("int: {0}", msgLength);
Console.WriteLine("msgL size: {0}", msgLengthBytes.Length);
//join arrays, file size info, TCP header
byte[] result = new byte[msgLengthBytes.Length + msgLength];
Buffer.BlockCopy(msgLengthBytes, 0, result, 0, msgLengthBytes.Length);
Buffer.BlockCopy(msg, 3, result, msgLengthBytes.Length, msgLength);
//file extension info, TCP Header
byte extension = 2; //file extension code
byte[] newArray = new byte[result.Length + 1];
result.CopyTo(newArray, 1);
newArray[0] = extension;
result = newArray;
int bytesSent = sender.Send(result);
Console.WriteLine("result size: {0}", result.Length);
sender.Shutdown(SocketShutdown.Both);
sender.Close();
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
private static byte[] GetBinaryFile(string filename)
{
byte[] bytes;
using (FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read))
{
bytes = new byte[file.Length];
file.Read(bytes, 0, (int)file.Length);
}
return bytes;
}
public static void Main(String[] args)
{
StartClient();
}
}
At the server side I have the following code:
class ProgramServer
{
public static void Main(String[] args)
{
try
{
StartListening();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
public static void StartListening()
{
byte[] bytes = new Byte[1024];
while (true)
{
string outputPath = string.Empty;
outputPath = #"C:\output\output";
Console.WriteLine("Waiting for a connection...");
Socket handler = SocketInstance().Accept();
data = null;
//for the TCP header, get file extension
bytes = new byte[1];
int bytesReceivedExtension = handler.Receive(bytes);
string extension = GetExtension(bytes[0]);
outputPath = outputPath + extension;
//for the TCP header, get file size information
bytes = new byte[4];
int bytesReceived = handler.Receive(bytes);
int Lenght = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("msg length: " + Lenght);
int TotalReceivedBytes = 0;
while (TotalReceivedBytes < Lenght)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
TotalReceivedBytes = TotalReceivedBytes + bytesRec;
AppendAllBytes(outputPath, bytes);
}
Console.WriteLine("Bytes received total: " + TotalReceivedBytes);
Console.WriteLine(File.Exists(outputPath) ? "File received." : "File not received.");
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
private static Socket SocketInstance()
{
IPAddress ipAd = IPAddress.Parse("192.168.137.71");
IPEndPoint localEndPoint = new IPEndPoint(ipAd, 1234);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
return listener;
}
public static void AppendAllBytes(string path, byte[] bytes)
{
using (var stream = new FileStream(path, FileMode.Append))
{
stream.Write(bytes, 0, bytes.Length);
}
}
public static string GetExtension(byte extOfFile)
{
switch (extOfFile)
{
case 0:
return ".txt";
case 1:
return ".png";
case 2:
return ".iso";
default:
return "";
}
}
}
So, how can I be sure that my byte[] is OK? Because when I open that ISO file at the received side, its content is not OK. IS there some alternative for any type of file to binary conversion?
Thanks.
The framing protocol you made up seems to work like this:
0 1 2 3 4 ... N
[L][L][L][L][D][...][D]
Where L represents an 32-bit integer (in which endianness?) indicating the lenght of the Data.
First, you're sending the wrong file length:
byte[] msgLengthBytes = BitConverter.GetBytes(msg.Length-3);
Why do you subtract 3? You shouldn't. This causes the last 3 bytes to be chopped off the file.
Then when filling the message buffer, you start writing at byte 3, or the last byte of L:
Buffer.BlockCopy(msg, 3, result, msgLengthBytes.Length, msgLength);
This will cause the reader to interpret an incorrect data length. You should start at byte 4.
Third, when writing the file, you shouldn't append the entire buffer, but only the bytes that Receive() actually wrote in the buffer:
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
TotalReceivedBytes = TotalReceivedBytes + bytesRec;
AppendAllBytes(outputPath, bytes, bytesRec);
Then in that method:
public static void AppendAllBytes(string path, byte[] bytes, int bufferLength)
{
using (var stream = new FileStream(path, FileMode.Append))
{
stream.Write(bytes, 0, bufferLength);
}
}
And this is why you shouldn't write your own protocol and socket code if you don't know very well what you're doing. Leverage existing protocols and libraries instead.

Half file transferring in c# via socket?

I am developing the file transfer application via middle level greedy routing in which file sends to greedy and greedy sends file again to router
but he problem is some time client receives complete file and some time it receive some part of file
Here my code goes
Server Side
IPAddress[] ipAddress = Dns.GetHostAddresses("127.0.0.1");
IPEndPoint ipEnd = new IPEndPoint(ipAddress[0], 5655);
Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
string filePath = "";
fileDes = fileDes.Replace("\\", "/");
while (fileDes.IndexOf("/") > -1)
{
filePath += fileDes.Substring(0, fileDes.IndexOf("/") + 1);
fileDes = fileDes.Substring(fileDes.IndexOf("/") + 1);
}
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileDes);
lblError.Text = "";
lblError.Text = "Buffering ...";
byte[] fileData = File.ReadAllBytes(filePath + fileDes);
byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length];
byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);
fileNameLen.CopyTo(clientData, 0);
fileNameByte.CopyTo(clientData, 4);
fileData.CopyTo(clientData, 4 + fileNameByte.Length);
lblError.Text = "";
lblError.Text = "Connection to server ...";
clientSock.Connect(ipEnd);
lblError.Text = "";
lblError.Text = "File sending...";
// System.Threading.Thread.Sleep(1000);
clientSock.Send(clientData);
label3.Text = clientData.Length.ToString();
lblError.Text = "";
lblError.Text = "Disconnecting...";
clientSock.Close();
lblError.Text = "";
lblError.Text = "File transferred.";
In client
class DestCode
{
IPEndPoint ipEnd;
Socket sock;
public DestCode()
{
ipEnd = new IPEndPoint(IPAddress.Any, 5656);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
}
public static string receivedPath;
public static string curMsg = "Stopped";
public static int res;
public void StartServer()
{
try
{
curMsg = "Starting...";
sock.Listen(100);
curMsg = "Running and waiting to receive file.";
Socket clientSock = sock.Accept();
byte[] clientData = new byte[1024 * 5000];
int receivedBytesLen = clientSock.Receive(clientData);
curMsg = "Receiving data...";
int fileNameLen = BitConverter.ToInt32(clientData, 0);
string fileName = Encoding.ASCII.GetString(clientData, 4, fileNameLen);
BinaryWriter bWrite = new BinaryWriter(File.Open(receivedPath +"/"+ fileName, FileMode.Append)); ;
bWrite.Write(clientData,4 + fileNameLen, receivedBytesLen - 4 - fileNameLen);
res = receivedBytesLen;
if (receivedPath == "")
{
MessageBox.Show("No Path was selected to Save the File");
}
curMsg = "Saving file...";
bWrite.Close();
clientSock.Close();
curMsg = "File Received ...";
StartServer();
}
catch (Exception ex)
{
curMsg = "File Receving error.";
}
}
}
In Greedy
class ReceiverCode
{
IPEndPoint ipEnd;
Socket sock;
public ReceiverCode()
{
ipEnd = new IPEndPoint(IPAddress.Any, 5655);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
sock.Bind(ipEnd);
}
public static string receivedPath;
public static string curMsg = "Stopped";
public static string Rout = "";
public static int rlength = 0;
public static string MsgStatus = "";
public static byte[] send;
public void StartServer()
{
try
{
curMsg = "Starting...";
sock.Listen(100);
curMsg = "Running and waiting to receive file.";
Socket clientSock = sock.Accept();
byte[] clientData = new byte[1024 * 5000];
int receivedBytesLen = clientSock.Receive(clientData);
System.Threading.Thread.Sleep(5000);
rlength = receivedBytesLen;
curMsg = "Receiving data...";
int receive = clientSock.Receive(clientData);
send = new byte[receivedBytesLen];
Array.Copy(clientData, send, receivedBytesLen);
Rout = "Start";
clientSock.Close();
curMsg = "Reeived & Saved file; Server Stopped.";
StartServer();
}
catch (Exception ex)
{
curMsg = "File Receving error.";
}
}
}
Please somebody help me
The problem is that Socket.Receive does not guarantee that you'll receive all the bytes you asked for. So you write:
int receivedBytesLen = clientSock.Receive(clientData);
The documentation says:
If you are using a connection-oriented Socket, the Receive method will read as much data as is available, up to the size of the buffer.
The call to Receive is getting all of the bytes that are currently available. It could be that the sender hasn't yet sent all of the bytes, or that your network stack hasn't received them and made them available.
To reliably send and receive data, the receiver has to know one of two things: either how many bytes it's expecting, or that there is some sentinel value that says, "that's all, folks." You can't count on a single Receive call to get everything.
When transferring files, the sender typically includes the size of the file as the first four bytes of the data being sent. Your code then reads the first four bytes (making sure that you get all four bytes) to determine the size, and then spins a loop, reading data from the socket until all of the expected bytes are received.
Something like:
const int MaximumSize = 1000000;
// read the first four bytes
var sizeBytes = ReadBytesFromSocket(socket, 4);
int size = BitConverter.ToInt32(sizeBytes);
var dataBuffer = ReadBytesFromSocket(socket, size);
// you now have your data
byte[] ReadBytesFromSocket(Socket socket, int size)
{
var buff = new byte[size];
int totalBytesRead = 0;
while (totalBytesRead < size)
{
int bytesRead = socket.Receive(buff, totalBytesRead, size-totalBytesRead, SocketFlags.None);
if (bytesRead == 0)
{
// nothing received. The socket has been closed.
// maybe an error.
break;
}
totalBytesRead += bytesRead
}
return buff;
}
See my blog post on reading streams (and the linked parts 1 and 2) for more information. The blog posts talk about streams, but the concepts are the same with sockets.

Send a file from server to client in GWT

I am using GWT.
I have to download a file file from server to client.
Document is in the external repository.
Client sends the id of the document through a Servlet.
On server side: Using this ID document is retrieved:
Document document = (Document)session.getObject(docId);
ContentStream contentStream = document.getContentStream();
ByteArrayInputStream inputStream = (ByteArrayInputStream) contentStream.getStream();
int c;
while ((c = inputStream.read()) != -1) {
System.out.print((char) c);
}
String mime = contentStream.getMimeType();
String name = contentStream.getFileName();
InputStream strm = contentStream.getStream();
Here I can read the document.
I want to send this to the client.
How do I make this a file and send it back to the client?
In Your Servlet:
Document document =(Document)session.getObject(docId);
ContentStream contentStream = document.getContentStream();
String name = contentStream.getFileName();
response.setHeader("Content-Type", "application/octet-stream;");
response.setHeader("Content-Disposition", "attachment;filename=\"" + name + "\"");
OutputStream os = response.getOutputStream();
InputStream is =
(ByteArrayInputStream) contentStream.getStream();
BufferedInputStream buf = new BufferedInputStream(is);
int readBytes=0;
while((readBytes=buf.read())!=-1) {
os.write(readBytes);
}
os.flush();
os.close();// *important*
return;
You can create a standard servlet (which extends HttpServlet and not RemoteServiceServlet) on server side and opportunity to submit the id as servlet parameter on client side.
Now you need after getting request create the excel file and send it to the client. Browser shows automatically popup with download dialog box.
But you should make sure that you set the right content-type response headers. This header will instruct the browser which type of file is it.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String fileId = reguest.getParameter("fileId"); // value of file id from request
File file = CreatorExel.getFile(fileId); // your method to create file from helper class
// setting response headers
response.setHeader("Content-Type", getServletContext().getMimeType(file.getName()));
response.setHeader("Content-Length", file.length());
response.setHeader("Content-Disposition", "inline; filename=\"" + file.getName() + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
InputStream inputStream = new FileInputStream(file);
ServletOutputStream outputStream = response.getOutputStream();
input = new BufferedInputStream(fileInput);
output = new BufferedOutputStream(outputStream);
int count;
byte[] buffer = new byte[8192]; // buffer size is 512*16
while ((count = input.read(buffer)) > 0) {
output.write(buffer, 0, count);
}
} finally {
if (output != null) {
try {
output.close();
} catch (IOException ex) {
}
}
if (input != null) {
try {
input.close();
} catch (IOException ex) {
}
}
}