ClosedChannelException on Socket - java

I am trying to build a TCP/IP sniffer for android using VpnService.I modified ToyVpn example I am correctly getting the output IP packet from the descriptor and for the moment I am just trying to send it to the destination socket without IP and TCP headers and show in Log the response from the destination server. Actualy, what I have to do is to deliver the packet in the network and when I have a response write it in the OutputStream coresponding to the ParcelFileDescriptor.
I am using this code:
while (vpnInterface != null && vpnInterface.getFileDescriptor() != null
&& vpnInterface.getFileDescriptor().valid()) {
packet.clear();
// Read the outgoing packet from the input stream.
final byte[] data = packet.array();
int length = in.read(data);
//use this to get the unsigned byte
int[] d = new int[data.length];
if (length > 0) {
packet.limit(length);
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < data.length; i++) {
d[i] = data[i] & 0xFF;
sb.append(d[i] + " ");
}
Log.i("packet", sb.toString());
Socket socket = SocketChannel.open().socket();
if ((null != socket) && (null != this)) {
this.protect(socket);
}
//connect to dest ip and port
socket.connect(new InetSocketAddress(d[16] + "." + d[17] + "."
+ d[18] + "." + d[19], (d[22] * 256) + d[23]));
DataOutputStream dOut = new DataOutputStream(
socket.getOutputStream());
DataInputStream dIn = new DataInputStream(
socket.getInputStream());
dOut.write(data, 40, data.length - 40);
dOut.flush();
dOut.close();
length = dIn.read(data);
if (length > 0) {
sb = new StringBuilder("");
for (int i = 0; i < data.length; i++) {
d[i] = data[i] & 0xFF;
sb.append(d[i] + " ");
}
Log.i("response", sb.toString());
dIn.close();
}
}
Thread.sleep(10);
}
The problem is that I get ClosedChannelException when trying to read the InputStream from the socket. Do you have any ideea why is this happening? The ideea is that I don't know how to manage the input packets from the dest socket.
Sorry if I made any mistake but I am beginner in JAVA.

You're closing the InputStream that you've got from the Socket. JavaDoc says:
Closing the returned InputStream will close the associated socket.
Usually, you should never close a stream that you do not own!
The same is true for the OutputStream you get with socket.getOutputStream(). If you close it, the socket will be closed too!

Related

Transferring Files via TCP/IP works in Windows but not Ubuntu

I was trying my hands at sending multiple files using TCP/IP connection with the help of this guide.
When I execute my testClient codes from Ubuntu 14.04, files are transferred over to testServer in Windows 7. The .txt files received here are in correct format.
However, when I execute testClients codes from Windows 7 and testServer from Ubuntu 14.04, the files received in Ubuntu 14.04 was messed up. (The contents from txt#2 contents spill over to txt#1.)
During the swap, none of the codes in both testServer and testClients were changed other than their IP address and file location.
I am confused. Why did the codes work fine in Windows 7 but not in Ubuntu? Is there something wrong with my codes? I would appreciate any help on this.
TestServer.java
public static void main(String[] args) throws IOException {
FileOutputStream fos;
BufferedOutputStream bos;
OutputStream output;
DataOutputStream dos;
int len;
int smblen;
InputStream in;
boolean flag = true;
DataInputStream clientData;
BufferedInputStream clientBuff;
ServerSocket serverSocket = new ServerSocket(5991);
serverSocket.setSoTimeout(500000);
System.out.println("Waiting for client on port " + serverSocket.getLocalPort());
Socket clientSocket = null;
clientSocket = serverSocket.accept();
System.out.println("Just connected to " + clientSocket.getRemoteSocketAddress());
while (true){
while(flag==true) {
in = clientSocket.getInputStream();
clientData = new DataInputStream(in);
clientBuff = new BufferedInputStream(in);
int fileSize = clientData.read();
if (fileSize != 0)
System.out.println("Receiving " + fileSize + " files.\n");
//Store filenames and file sizes from client directory
ArrayList<File>files=new ArrayList<File>(fileSize);
ArrayList<Integer>sizes = new ArrayList<Integer>(fileSize);
//Server accepts filenames
for (int count=0; count<fileSize; count ++){
File ff=new File(clientData.readUTF());
files.add(ff);
}
for (int count=0; count<fileSize; count ++){
sizes.add(clientData.readInt());
}
for (int count=0; count<fileSize; count++) {
if (fileSize - count == 1) {
flag = false;
}
len = sizes.get(count);
output = new FileOutputStream("/home/pp/Desktop/inResources/" + files.get(count));
dos = new DataOutputStream(output);
bos = new BufferedOutputStream(output);
byte[] buffer = new byte[1024];
bos.write(buffer, 0, buffer.length);
while (len > 0 && (smblen = clientData.read(buffer)) > 0) {
dos.write(buffer, 0, smblen);
len = len - smblen;
dos.flush();
}
dos.close();
System.out.println("File " + files.get(count) + " with " + sizes.get(count) + " bytes recieved.");
}
}
if (flag == false) {
System.out.println("\nTransfer completed. Closing socket...");
serverSocket.close();
break;
}
}
}
TestClient.java
public static void main(String[] args) throws IOException {
String serverName = "192.168.1.12"; //IP address
int port = 5991;
Socket sock = new Socket(serverName, port);
System.out.println("Connected to " + serverName + " on port " + port + "\n");
File myFile = new File("C:\\Users\\inter2\\Desktop\\noobs\\outResources");
File[] files = myFile.listFiles();
OutputStream os = sock.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
//Sending total number of files in folder
dos.writeInt(files.length);
//Sending file names
for (int count=0; count<files.length; count++) {
dos.writeUTF(files[count].getName());
}
//Sending file sizes
for (int count=0; count<files.length; count++) {
int filesize = (int) files[count].length();
dos.writeInt(filesize);
}
//Sending of files
for (int count=0; count<files.length; count ++) {
int filesize = (int) files[count].length();
byte [] buffer = new byte [filesize];
FileInputStream fis = new FileInputStream(files[count].toString());
BufferedInputStream bis = new BufferedInputStream(fis);
//Sending file name and file size to the server
bis.read(buffer, 0, buffer.length);
dos.write(buffer, 0, buffer.length);
dos.flush();
System.out.println("Sending file " + files[count].getName() + " with " + filesize + " bytes.");
}
System.out.println("\n" + files.length + " files successfully transfered.");
sock.close();
}
This code never worked.
int fileSize = clientData.read();
Here you are reading the amount of files, as a byte.
dos.writeInt(files.length)
Here you are writing that amount, as an int. So already your writer is three bytes ahead of your reader.
Change read() to readInt() above.
Other notes:
Receiving:
byte[] buffer = new byte[1024];
This is OK but a bigger buffer would be more efficient, say 8192.
bos.write(buffer, 0, buffer.length);
This is a bug. Remove it. You are writing 1024 null bytes at the beginning of the file.
while (len > 0 && (smblen = clientData.read(buffer)) > 0) {
dos.write(buffer, 0, smblen);
len = len - smblen;
dos.flush();
Don't flush inside loops.
}
Sending:
byte [] buffer = new byte [filesize];
FileInputStream fis = new FileInputStream(files[count].toString());
BufferedInputStream bis = new BufferedInputStream(fis);
//Sending file name and file size to the server
bis.read(buffer, 0, buffer.length);
dos.write(buffer, 0, buffer.length);
No need to waste a buffer of the size of the file. Use the same code you use for receiving above.

How to get the file name from an RRQ datagramPacket?

Im working on a TFTP server. Basing on the image the max length of my packets is 516 bytes (2+2+512).
I'm trying to take the original length from the client datagrampacket(in this case sends 13 bytes in a RRQ packet), instead im getting the server datagrampacket length (516 bytes) where i save the client datagrampacket.
I need that for extract the filename, i did that but the string content is "filename + nullBytes", those null bytes come from the server datagrampacket.
This is the code where im stuck:
public static short RRQ = 1;
enter code here
public void dataMetod() throws IOException{
byte[] packet = new byte[516];
//socket with listening port 5000
DatagramSocket datagramSocket = new DatagramSocket(5000);
//while receive packets
while (true) {
DatagramPacket datagramPacket = new DatagramPacket(packet,packet.length);
datagramSocket.receive(datagramPacket);
System.out.println("server: new packet!!:");
//create a byte[] with the "received packet length"(that's not true)
byte[] inData = new byte[datagramPacket.getLength()];
inData = datagramPacket.getData();
System.out.println("length: "+inData.length);
byte code;
code = inData[1];
System.out.println(code);
//check if its an RRQ packet
if (code == RRQ) {
System.out.println("server: RRQ PACKET!!");
String fileName = this.getFileName(inData);
System.out.println(fileName);
}
public String getFileName(byte[] inData) {
byte[] aux = new byte[inData.length - 7];
for (int i = 0; i < aux.length; i++) {
aux[i] = inData[i + 2];
}
return new String(aux);
}
http://i.stack.imgur.com/6dTH6.png
Try this:
public String getFileName(byte[] inData) {
final int maxLen = inData.length;
final StringBuilder sb = new StringBuilder();
int i = 2;
byte b;
while ( (i < maxLen) && (b = inData[i]) != 0 ) {
final int v = ((int)b) & 0xff;
sb.append( (char) v );
i++;
}
return sb.toString();
}
Instead of getting the original length of the received packet(to search the file name through the array), we could do that by adding "\n" at fileName String in client class, then use BufferedReader which will detect "\n" and save the fileName.
Code:
public String getFileName(byte[] inData) throws IOException {
//get a sub-array, from index[2] (beacuse we dont want opCode) to inData length
byte[] b =Arrays.copyOfRange(inData, 2, inData.length);
InputStream is = new ByteArrayInputStream(b);
BufferedReader bf = new BufferedReader(new InputStreamReader(is));
//We read a word that will be saved when "\n" is found.
//(adding "\n" previously to the fileName String in client class)
String filename = bf.readLine();
bf.close();
is.close();
System.out.println("server: filename is: "+filename.length()+" bytes");
return filename;
}

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

Connection reset by peer: socket write error c++ - java

I am trying to write a server-client application for file transfer. The client is written in Java and the server is written in C++.
Unfortunately I have the following error:
java.net.SocketException: Connection reset by peer: socket write error"
Here is my code for client:
import java.io.*;
import java.net.Socket;
public class Proba_binar
{
public static void main(String[] args)
{
byte[] buffer = null;
byte[] auxByte = new byte[1000];
String fileName = "1.jpg";
File a_file = new File(fileName);
try
{
// Create a socket
Socket socket = new Socket("192.168.14.146", 8888);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// Read file
FileInputStream fis = new FileInputStream(fileName);
int length = (int)a_file.length();
buffer = new byte[length];
fis.read(buffer);
fis.close();
// Send file length
System.out.println("length = " + Integer.toString(length));
out.write(Integer.toString(length) + "\n");
out.flush();
// Send file
int imageSize = buffer.length;
char[] auxChar = new char[1000];
int nr_transf = imageSize / 1000;
int rest_byte = imageSize % 1000;
System.out.println("nr_transf = " + nr_transf);
for(int j = 0; j < nr_transf; j++)
{
// send series of 1000 bytes
for(int i = 0; i < 1000; i++)
{
auxChar[i] = (char)buffer[j*1000+i];
auxByte[i] = buffer[j*1000+i];
}
out.write(auxChar);
out.flush();
}
// send last bytes
for(int i = 0; i < rest_byte; i++)
{
auxChar[i] = (char)buffer[1000*nr_transf+i];
auxByte[i] = buffer[1000*nr_transf+i];
}
out.write(auxChar, 0, rest_byte);
out.flush();
out.close();
in.close();
socket.close();
System.out.println("Transfer finished!");
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
And the code for server:
int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s , new_socket;
struct sockaddr_in server , client;
int c, bytecount, nr_transf, rest_byte, i;
int recv_size, file_size;
char message[1000];
char buffer[1000];
int buffer_len = 1000;
FILE *f = fopen("out.jpg", "wb");
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2, 2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
getch();
return 0;
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if(bind(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
getch();
return 0;
}
puts("Bind done");
//Listen to incoming connections
listen(s, 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
new_socket = accept(s, (struct sockaddr*)&client, &c);
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d", WSAGetLastError());
getch();
return 0;
}
puts("Connection accepted");
//Receive FILE DIMENSION from client
if((recv_size = recv(new_socket, message, 1000, 0)) == SOCKET_ERROR)
{
puts("recv failed");
getch();
}
message[recv_size] = '\0';
file_size = atoi(message);
printf("\nfile_size = %d", file_size);
nr_transf = file_size / 1000;
rest_byte = file_size % 1000;
//Receive FILE from client
for(i = 0; i < nr_transf; i++)
{
// receive 1000 bytes
if((bytecount = recv(new_socket, buffer, buffer_len, 0)) == SOCKET_ERROR)
{
printf("Receive failed auxChar");
getch();
return 0;
}
fwrite(buffer, 1, buffer_len, f);
}
// receive last bytes
if((bytecount = recv(new_socket, buffer, rest_byte, 0)) == SOCKET_ERROR)
{
printf("Receive failed rest_byte");
getch();
return 0;
}
fwrite(buffer, 1, rest_byte, f);
fclose(f);
printf("Receive finished!");
closesocket(s);
WSACleanup();
getch();
return 0;
}
I made equivalent server in Java and works perfectly.
I do not know what the problem is in c + + version.
Thanks in advance!
recv() does not guarantee that it will read all bytes requested:
...calling recv will return as much data as is currently available—up to the size of the buffer specified...
This means that the for/recv loop is incorrectly structured and it is probably the case that the server believes it has read all the data but it has not. This results in the server closing the socket before the client has sent all the data, resulting in the error reported by the Java client.
Example (untested) restructuring of the recv loop:
int totalBytesRead = 0;
int bytesRead;
while (totalBytesRead < file_size)
{
if((bytesRead = recv(new_socket, buffer, buffer_len, 0)) == SOCKET_ERROR)
{
/* Handle failure. */
break;
}
if (bytesRead != fwrite(buffer, 1, bytesRead, f))
{
/* Handle failure. */
break;
}
totalBytesRead += file_size;
}
Remember that connected sockets are stream based, using mutilple send()s does not imply that the matching recv()s will read the data in the same "chunks" as they were sent. In addition to the data content retrieval error already mentioned, this equally applies to the reading of the file size. There is no guarantee that entire file size will be read.
I would recommend designing a simple protocol to ensure the different types of data are correctly read. For example, client sends:
<file_size>\n<file_content>
the server reads all data up to the newline character and converts it into the file size. The server then knows for certain it has the correct file size. The server then reads file_size bytes from the socket. Finally, server responds to indicate success or failure:
success\n
the client reads up to the newline character to obtain the response.

Sending large data over sockets in java

I am working on client server architecture and i am just beginner in this thing. Here my server is of C and client is of Java and i want to send a binary/database (.db)/image file of size around 10 - 20 MB from C server to the Java client. But data is lost while implementing the following code:
Server side C code is:
int sockfd, newsockfd, portno, clilen;
struct sockaddr_in serv_addr, client_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
strcpy(message,"Error opening socket");
eFlag = 1;
send_message(message);
}
bzero((char *)&serv_addr, sizeof(serv_addr));
portno = 6789;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if(bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
strcpy(message,"Error on binding");
eFlag = 1;
send_message(message);
}
listen(sockfd, 5);
clilen = sizeof(client_addr);
newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &clilen);
if(newsockfd < 0)
{
strcpy(message,"Error on accept");
eFlag = 1;
send_message();
exit(4);
}
void send_file()
{
buffer = (char *)malloc(sizeof(char)*lSize);
result = fread(buffer, sizeof(char), lSize, fp);
printf("\n\n########## data read into buffer successfully #######");
if(newsockfd)
{
n = send(newsockfd, buffer, lSize);
printf("\n\n$$$$$$$$ Data sent successfully $$$$$");
strcpy(message,"Data sent successfully");
send_message(message);
}
else
{
strcpy(message, "Error writing on socket");
send_message(message);
}
sleep(sleepTime);
sleepTime = (int) (sleepTime*1.02);
free(buffer);
}
And, my client side Java code is:
final int PORT_NO = 6789;
final String Server_name = "192.133.133.1";
Socket m_socket = null;
String str;
int ch;
try {
if(m_socket == null)
m_socket = new Socket(Server_name, PORT_NO);
if(m_socket == null)
System.out.println("Unable to open the socket");
DataInputStream dis = new DataInputStream(m_socket.getInputStream());
PrintStream ps = new PrintStream(m_socket.getOutputStream());
DataInputStream ds = new DataInputStream(System.in);
while(true)
{
System.out.println("1. Synchronize");
System.out.println("2. Exit");
System.out.println("Enter your choice...");
str = ds.readLine();
ch = Integer.parseInt(str);
switch(ch)
{
case 1:
ps.println("<message action='buttonpress' value='synchronize' />");
System.out.println("avilable data to read is:"+dis.available());
FileOutputStream fos = new FileOutputStream("mukul.db");
byte data[] = new byte[102400]; //100 Kb byte array
dis.read(data);
String str_data = new String(data);
str_data = str_data.trim();
data = str_data.getBytes();
fos.write(data);
fos.close();
break;
here only part of data is read i.e around 10 kb or less.
I am just a beginner to such posts and my code may be cumbersome, so please ignore all the mistakes in posting.
So please kindly tell me how can i receive 1 MB/10 MB of data in this client-server architecture without the loss of data.
What if i use "sendfile(out_fp, in_fp, pos, len)" method in C code instead of "send()". This method sends file handle. So what will be the corresponding function in Java to capture file handle.
Thank you in advance.
You're misusing the send()/recv() functions. send() and recv() are not required to send as much data as you request, due to limits that may be present in the kernel. You have to call send() over and over until all data has been pushed through.
e.g.:
int sent = 0;
int rc;
while ( sent < should_send )
{
rc = send(sock, buffer + sent, should_send - sent, 0);
if ( rc <= 0 ) // Error or hangup
// do some error handling;
sent += rc;
}
Java side,
int lent2 = 0;
int LengthToReceive = 102400;
char[] chTemp = new char[LengthToReceive];
while (true) {
int readlength = bufferedreader.read(chTemp, lent2,LengthToReceive - lent2);
if(readlength==-1){
break;
}
lent2 += readlength;
if (lent2 >= LengthToReceive) {
flag = false;
break;
}
}
m_socket can't possibly be null the line after you call m_socket = new Socket(...). It will either throw an exception or assign a Socket to m_socket, never null. So that test is pointless.
After you call readLine() you must check for a null return value, which means EOS, which means the other end has closed the connection, which means you must exit the reading loop and close the socket.
As it says in the Javadoc, InputStream.available() shouldn't be used for a test for EOS. Its contract is to return the number of bytes that can be read without blocking. That's rarely the same as the length of an incoming file via a socket. You must keep reading the socket until EOS:
int count;
byte[] buffer = new byte[8192];
while ((count = in.read(buffer)) > 0)
out.write(buffer, 0, count);
If your sending end doesn't close the socket when it finishes sending the file you will have to have it send the file length ahead of the file, and modify the loop above to read exactly that many bytes.

Categories

Resources