i have written the following code to download file.
java.io.BufferedInputStream in =
new java.io.BufferedInputStream(new java.net.URL(url).openStream());
java.io.FileOutputStream fos = new java.io.FileOutputStream(filename);
java.io.BufferedOutputStream bout = new BufferedOutputStream(fos,1024);
byte[] data = new byte[1024];
int x=0;
while((x=in.read(data,0,1024))>=0)
{
bout.write(data,0,x);
}
if(filename.equalsIgnoreCase("table.csv"))
{
updateflag=true;
}
if(filename.equalsIgnoreCase("quotes.csv"))
{
quoteupdate=true;
}
bout.flush();
bout.close();
in.close();
Now, when a file named "table.csv" is passed as paramenter to download function, everything works smooth. Problem is when i try to download "quotes.csv" after i download "table.csv".
The exact calling is this:
url="http://ichart.finance.yahoo.com/table.csv? s=%5EBSESN&a=00&b=31&c=2011&d="+(month-1)+"&e="+day+"&f="+year+"&g=d&ignore=.csv";
updateflag=true;
downloadDB("table.csv",url);
System.out.print("quotes to download");
url="http://download.finance.yahoo.com/d/quotes.csv?
s=%5EBSESN&f=sl1d1t1c1ohgv&e=.csv";
if(candownload==true)
{
downloadDB("quotes.csv",url);
}
candownload=false;
I get error saying : Unrecognized Windows Socket error:0: JVM_BIND
Now i understand JVM_BIND is saying i have a process already attached to port 80.
However, i have closed all streams at the end of my function. Why is this happening then?
Thanks in advance
I don't have enough privileges to post comments so my apologies for providing an answer that may not get to the exact problem.
Leaving streams open won't necessarily cause this problem AFAIK. It's really caused by trying to bind a new Server Socket when one is already existing. So... maybe you should check to see if your code is trying to bind a new ServerSocket every time (with the same port) the download function is called. You really shouldn't need to do that. Bind once, and in the accept method spawn a new thread that does the download.
Related
I am quite new to StackOverflow, if my question is inappropriately asked or confusing, please let me know, thank you!
I am working on an audio streaming project, in which the clients are allowed to upload their mp3 files to the server. The server will store them into a playlist and stream the songs back to all the clients.
Here is my code for the client to upload the mp3:
public static void sendPackets(){
System.out.println("Sending test file...");
try{
while (active){
//The song needs to be uploaded;
File file = new File("Sorrow.mp3")
FileInputStream fis = new FileInputStream(file);
byte[] byteStream = new byte[(int) file.length()];
//Trying to convert mp3 to byteStream
fis.close();
InetAddress destination = InetAddress.getByName("localhost");
DatagramPacket sendingAirMail = new DatagramPacket(byteStream, byteStream.length, destination, 50010); // 50010 is the listening port
serverSocket.send(sendingAirMail); // sending the entire bytestream via UDP
// ServerSocket is a DatagramSocket
break;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The Problem lies here:
serverSocket.send(sendingAirMail);
As it will give me this error:
java.net.SocketException: The message is larger than the maximum supported by the underlying transport: Datagram send failed
at java.base/java.net.DualStackPlainDatagramSocketImpl.socketSend(Native Method)
at java.base/java.net.DualStackPlainDatagramSocketImpl.send(DualStackPlainDatagramSocketImpl.java:136)
at java.base/java.net.DatagramSocket.send(DatagramSocket.java:695)
at client.sendPackets(client.java:116)
at client$2.run(client.java:67)
After looking up google, I learned that it is because the UDP has a limit of size in each package delivered, so I wish to know how to separate the UDP package properly in this case? I know the TCP will be better in this case, but I think I need to learn how to separate packages anyway because I need to stream back the byte arrays from the server using UDP. Any help will be appreciated!
I can post my server and other client information if needed.
The thing is that you need to cut your file into several pieces and deliver them. For UDP, you need some things to make sure the file is complete and correct. Here are some suggestions:
First, you need to cut your file, so you need to give a seq flag in the head. What's more you may need some extra infomations like the whole size of file, the timestamp and so on.
struct msg {
int seq;
int total_seq;
int size;
void *data;
};
Then, it's better to build a send buffer and recive buffer, check every time if the buffer is empty, if not, send/receive it.
After receiving some pieces, you need to rebuild them using the seq flag. When some seq gets lost, you need retransmission. So you need a retransmission design here.
In a word, you need the following things at least:
A user defined head before information
cut/rebuild file
retransmission(GBN or FEC or both)
Hope that can help you.
This problem really has me stumped. I'm sending images from a client to a server using ObjectOutputStream, but over time the java heap keeps growing. This eventually causes an OutOfMemoryError exception. After some online research, the reset method seems to be the only solution. Which is great, but using it causes an error: mark/reset not supported. The only page I could find on this was here:
https://stackoverflow.com/questions/38814424/how-can-i-get-an-objectinputstream-that-supports-mark-reset
I'm not really sure what to do with that page's answer.
Anyway, here's the server code:
ServerSocket vchatserver = new ServerSocket(6677);
Socket c1 = vchatserver.accept();
ObjectInputStream ois = new ObjectInputStream(c1.getInputStream());
while(c1.isConnected()) {
ImageIcon icon = (ImageIcon) ois.readUnshared();
ois.reset();
}
And now the client's code:
Socket vchatclient = new Socket(pub_serverName, 6677);
ObjectOutputStream oos = new ObjectOutputStream(vchatclient.getOutputStream());
while(vchatclient.isConnected()) {
ImageIcon img = new ImageIcon(webcam.getImage());
oos.writeUnshared(img);
oos.reset();
Thread.sleep(25);
}
The object input stream doesn't support mark/reset. But you don't need it. You don't need to call reset() on the input stream. ObjectOutputStream.reset() is sufficient.
The question you linked is irrelevant.
NB while (c1.isConnected()) is not a valid test for end of stream. You need to catch EOFException. Similarly while (vchatclient.isConnected()) will not protect you from IOExceptions when writing. This method only tells you whether you have ever connected this socket. It doesn't tell you anything about the current state of the connection.
I'm trying to invoke a method from another class that means I want to use serialization I make an object of method name and it's parameters and write it on a socket but when I want to make ObjectOutputStream I encounter with error "connection reset by peer: socket write error"
I searched for the possible reasons but I couldn't find any suitable answer
in the server side I didn't close the sockets or I didn't do any work to close that I don't know what happens then :-??
in the line:
ObjectOutputStream oos = (new ObjectOutputStream(os));
and my piece of code is this:
InvocationVO invo = new InvocationVO("showStart", treasure, round);
for (int i = 0; i < numPlayer; i++) {
OutputStream os = socket.get(i).getOutputStream();
ObjectOutputStream oos = (new ObjectOutputStream(os)); // this has error
oos.writeObject(invo);
oos.close();
os.close();
Client.getClients()[i].invoke();
}
thanks for your helps in advance!
You are writing to a connection that has already been closed by the peer. I find it hard to believe that didn't turn up in your search. The cause of the problem is firstly that you are closing oos, and therefore the socket, in this code, so (a) it won't run the second time, and (b) closing the socket causes the peer to get an EOS condition and close the socket, so (c) the second time you run this code you will run into at least two problems.
There is a third problem you haven't hit yet. You are creating a new ObjectOutputStream every time you run this code rather than using the same one for the life of the socket. Same goes for ObjectInputStream wherever you use it too. If you do what you are doing here you are liable to run into StreamCorruptedException: invalid type code.
I'm making a Network File Transfer System for transfering any kind of file over a network in java. The size also could be of any kind. Therefore I've used UTF-8 protocol for the task.
I'm providing the codes which I've made but the problem is some times the file gets transfered as it is, with no problem at all. But sometimes few kb's of data is just skipped at the receiving end, which actually restricts the mp3/video/image file to be opened correctly. I think the problem is with BUFFER. I'm not creating any buffer which, right now, I think may be of some use to me.
I would really appreciate if anyone could provide any help regarding the problem, so that the file gets transferred fully.
Client side : --->> File Sender
Socket clientsocket = new Socket(host,6789); // host contains the ip address of the remote server
DataOutputStream outtoserver = new DataOutputStream(clientsocket.getOutputStream());
try
{
int r=0;
FileInputStream fromFile1 = new FileInputStream(path); // "path" is the of the file being sent.
while(r!=-1)
{
r = fromFile1.read();
outtoserver.writeUTF(r+"");
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
clientsocket.close();
Server side: --->> File Receiver
ServerSocket welcome = new ServerSocket(6789);
Socket conn = welcome.accept();
try
{
String r1 = new String();
int r=0;
FileOutputStream toFile1 = new FileOutputStream(path); // "path" is the of the file being received.
BufferedOutputStream toFile= new BufferedOutputStream(toFile1);
DataInputStream recv = new DataInputStream(conn.getInputStream());
while(r!=-1)
{
r1 = recv.readUTF();
r = Integer.parseInt(r1);
toFile.write(r);
}
}
catch(Exception e)
{
System.out.println(e.toString());
}
I don't understand why you are encoding binary data as text.
Plain sockets can send and receive streams of bytes without any problems. So, just read the file as bytes using a FileInputStream and write the bytes to the socket as-is.
(For the record, what you are doing is probably sending 3 to 5 bytes for each byte of the input file. And you are reading the input file one byte at a type without any buffering. These mistakes and others you have made are likely to have a significant impact on file transfer speed. The way to get performance is to simply read and write arrays of bytes using a buffer size of at least 1K bytes.)
I'm not sure of this, but I suspect that the reason that you are losing some data is that you are not flushing or closing outtoserver before you close the socket on the sending end.
FOLLOW UP
I also noticed that you are not flushing / closing toFile on the receiver end, and that could result in you losing data at the end of the file.
The first problem I see is that you're using DataInputStream and DataOutputStream. These are for reading/writing primitive Java types (int, long etc), you don't need them for just binary data.
Another problem is that you're not flushing your file output stream - this could be causing the lost bytes.
An explicit flush might help the situation.
I am attempting to transfer files (MP3s about six megabytes in size) between two PCs using SPP over Bluetooth (in Java, with the BlueCove API). I can get the file transfer working fine in one direction (for instance, one file from the client to the server), but when I attempt to send any data in the opposite direction during the same session (i.e., send a file from the server to the client), the program freezes and will not advance.
For example, if I simply:
StreamConnection conn;
OutputStream outputStream;
outputStream = conn.openOutputStream();
....
outputStream.write(data); //Data here is an MP3 file converted to byte array
outputStream.flush();
The transfer works fine. But if I try:
StreamConnection conn;
OutputStream outputStream;
InputStream inputStream;
ByteArrayOutputStream out = new ByteArrayOutputStream();
outputStream = conn.openOutputStream();
inputStream = conn.openInputStream();
....
outputStream.write(data);
outputStream.flush();
int receiveData;
while ((receiveData = inputStream.read()) != -1) {
out.write(receiveData);
}
Both the client and the server freeze, and will not advance. I can see that the file transfer is actually happening at some point, because if I kill the client, the server will still write the file to the hard drive, with no issues. I can try to respond with another file, or with just an integer, and it still will not work.
Anyone have any ideas what the problem is? I know OBEX is commonly used for file transfers over Bluetooth, but it seemed overkill for what I needed to do. Am I going to have to use OBEX for this functionality?
It could be as simple as both programs stuck in blocking receive calls, waiting for the other end to say something... try adding a ton of log statements so you can see what "state" each program is in (ie, so it gives you a running commentary such as "trying to recieve", "got xxx data", "trying to reply", etc), or set up debugging, wait until it gets stuck and then stop one of them and single step it.
you can certainly use SPP to transfer file between your applications (assuming you are sending and receiving at both ends using your application). From the code snippet it is difficult to tell what is wrong with your program.
I am guessing that you will have to close the stream as an indication to the other side that you are done with sending the data .. Note even though you write the whole file in one chunk, SPP / Bluetooth protocol layers might fragment it and the other end could receive in fragments, so you need to have some protocol to indicate transfer completion.
It is hard to say without looking at the client side code, but my guess, if the two are running the same code (i.e. both writing first, and then reading), is that the outputStream needs to be closed before the reading occurs (otherwise, both will be waiting for the other to close their side in order to get out of the read loop, since read() only returns -1 when the other side closes).
If the stream should not be closed, then the condition to stop reading cannot be to wait for -1. (so, either change it to transmit the file size first, or some other mechanism).
Why did you decide to use ByteArrayOutputStream? Try following code:
try {
try {
byte[] buf = new byte[1024];
outputstream = conn.openOutputStream();
inputStream = conn.openInputStream();
while ((n = inputstream.read(buf, 0, 1024)) > -1)
outputstream.write(buf, 0, n);
} finally {
outputstream.close();
inputstream.close();
log.debug("Closed input streams!");
}
} catch (Exception e) {
log.error(e);
e.printStackTrace();
}
And to convert the outputStream you could do something like this:
byte currentMP3Bytes[] = outputStream.toString().getBytes();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(currentMP3Bytes);