Using websockets through the simple websockets for webgl asset in unity3d, can connect but can't transmit messages - unity3d

Just having a problem on my mac trying to send strings over web sockets using this https://www.assetstore.unity3d.com/en/#!/content/38367
Lots of adapted code below from here mainly http://www.codepool.biz/how-to-implement-a-java-websocket-server-for-image-transmission-with-jetty.html and the web socket sharp echotest example.
I can connect but there is no sign of strings in my Jetty server console window (on a ws server running in java(eclipse)).
Iā€™m basically just trying to send a ā€œ1ā€ to my server over a websocket connection with the unity editor (5) at the moment, to prompt the server to start sending PNG files encoded as byte arrays, so I can put them back together in a C# script and apply them to a texture.
this is the script, I want to attach it to a game object like a plane or a cube and display the updating images sent over the web socket from my Jetty server, but at the moment I'm just stuck trying to send a message and see it pop up in my eclipse console window.
using UnityEngine;
using System.Collections;
using System;
public class socketTexture : MonoBehaviour {
// Use this for initialization
IEnumerator Start () {
WebSocket w = new WebSocket(new Uri("ws://192.168.0.149:8080/"));
yield return StartCoroutine(w.Connect());
Debug.Log ("Connected");
w.SendString("I'm client");
w.SendString("1");
while (true)
{
byte[] reply = w.Recv();
if (reply != null)
{
Debug.Log ("Received: "+reply);
var tex = new Texture2D(300, 300, TextureFormat.PVRTC_RGBA4, false);
// Load data into the texture and upload it to the GPU.
tex.LoadRawTextureData(reply);
tex.Apply();
// Assign texture to renderer's material.
GetComponent<Renderer>().material.mainTexture = tex;
}
if (w.Error != null)
{
Debug.LogError ("Error: "+w.Error);
break;
}
yield return 0;
}
w.Close();
}
}
...And the relevant code from the jetty server, but this works, I've tested it with some javascript and I can load the PNGs back into the browser window, so I'm definitely doing something wrong in Unity
#OnWebSocketMessage //part request from websocket client (remote browser)
public void onMessage( String message) {
System.out.println("message");
if (message.equals("1") || message.equals("2") || message.equals("3") || message.equals("4") ) {
System.out.println("Part " + message + " joined");
System.out.println( UIMain.usersPath + "/" + message + ".png" );
final String testVar = ( UIMain.usersPath + "/" + message + ".png" );
task = new FileWatcher( new File(testVar) ) {
protected void onChange( File file ) {
// here we code the action on a change
System.out.println( "File "+ file.getName() +" has changed!" );
try {
File f = new File(testVar);
BufferedImage bi = ImageIO.read(f);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(bi, "png", out);
ByteBuffer byteBuffer = ByteBuffer.wrap(out.toByteArray());
mSession.getRemote().sendBytes(byteBuffer);
out.close();
byteBuffer.clear();
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Timer timer1 = new Timer(); {
timer1.schedule(task , new Date(), 40 );
}
}
else if (message.equals( "0")) {
zerocounter = zerocounter + 1;
if (zerocounter >= 2) {
task.cancel();
}
}
else if (message.equals( "Hi there, client here")) {
System.out.println( "Client says: " + message );
}
}
Any help would be really appreciated, been lurking on here for years, hopefully getting to the stage soon where I can help out others a bit too.
Benedict
Edit:
This is my console error message in Unity
FormatException: Invalid length. System.Convert.FromBase64String
(System.String s) (at
/Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Convert.cs:146)
EchoTest+c__Iterator0.MoveNext () (at
Assets/Example/EchoTest.cs:11)
I'm pretty sure the problem arises from websocket sharp for webgl. I need to send the message as a byte array.

OK So Joakim Erdfelt was right, the server was not configured to handle Byte[] messages. Here's what I added to fix it:
#OnWebSocketMessage
public void onMessage(byte[] buffer, int offset, int length) throws UnsupportedEncodingException {
System.out.println(buffer);
String sFclientOutStr = new String(buffer, "UTF-8");
sFclientOut = Integer.parseInt(sFclientOutStr);
System.out.println(sFclientOut);
if ((sFclientOut > 0) & (sFclientOut < 500)) {
System.out.println("Part " + sFclientOut + " joined");
System.out.println( UIMain.usersPath + "/" + sFclientOutStr + ".png" );
final String testVar = ( UIMain.usersPath + "/" + sFclientOutStr + ".png" );
task = new FileWatcher( new File(testVar) ) {
protected void onChange( File file ) {
// here we code the action on a change
System.out.println( "File "+ file.getName() +" has changed!" );
try {
File f = new File(testVar);
BufferedImage bi = ImageIO.read(f);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(bi, "png", out);
ByteBuffer byteBuffer = ByteBuffer.wrap(out.toByteArray());
mSession.getRemote().sendBytes(byteBuffer);
out.close();
byteBuffer.clear();
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Timer timer1 = new Timer(); {
timer1.schedule(task , new Date(), 40 );
}
}
else if (sFclientOutStr.equals("0")) {
zerocounter = zerocounter + 1;
if (zerocounter >= 2) {
task.cancel();
}
}
else if (sFclientOutStr.equals( "I'm client")) {
System.out.println( "Client says: " + sFclientOutStr );
}
}
These links helped explain it for me http://www.programcreek.com/java-api-examples/index.php?api=org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage
http://www.eclipse.org/jetty/documentation/current/jetty-websocket-api-annotations.html

Related

.net core 3.1 Worker Service

I am trying to create a TCP Listener as worker service. Any how managed to achieve the flow for Client Request and Server Response. But from browser when I try to browse the Url for the Application debugger hits the action method and writes the response in a stream but not able to return any response from the Main Thread of worker service i.e. ExecuteAsync method.
Any help in this regards would really help min completing this task.
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
Task.Run(() => _serverStatus = _tcpHandler.StartServer().Result).Wait();
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now
+ Environment.NewLine
+ String.Format("Server Started with status : {0}", _serverStatus)
+ Environment.NewLine
+ String.Format("Client Message : {0}", _tcpHandler.GetServerResponse())
+ Environment.NewLine
+ String.Format("Number of Requests recieved : {0}", _tcpHandler.GetRequestCounter()));
// _logger.LogInformation("Server running at: {0}", _tcpHandler.StartServer().Result);
await Task.Delay(1000, stoppingToken);
}
}
public async Task<string> StartServer()
{
string serverResponse = String.Empty;
try
{
await Task.Delay(1000);
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
serverResponse = "Status - Active";
// Perform a blocking call to accept requests.
// You could also use server.AcceptSocket() here.
_tcpClient = _tcpListener.AcceptTcpClientAsync().Result;
Console.WriteLine("Connected!");
Console.WriteLine(Environment.NewLine + "Waiting for Requests ...");
Thread t = new Thread(() => {
serverResponse = RequestHandler(_tcpClient).Result;
});
t.Start();
return serverResponse;
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
return "Status - Inactive";
}
}
public async Task<string> RequestHandler(object client)
{
string response = String.Empty;
try
{
// Set the TcpListener on port 13000.
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
// while (true)
//{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also use server.AcceptSocket() here.
TcpClient tcpClient = (TcpClient)client;
Console.WriteLine("Connected!");
data = null;
// Get a stream object for reading and writing
using (NetworkStream stream = tcpClient.GetStream())
{
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
_requestCounter++;
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
_requestedMessage = data;
Console.WriteLine("Message Received by Server: {0}", data);
// Process the data sent by the client.
data = "Hey ! Client ..." + data.ToUpper();
string xml = Environment.NewLine + "<Messages>"
+ Environment.NewLine + "<Message>"
+ Environment.NewLine + "<Date>" + DateTime.Now.ToString() + "</Date>"
+ Environment.NewLine + "<Text>" + data + "</Text>"
+ Environment.NewLine + "<status>" + "accepted" + "</status>"
+ Environment.NewLine + "<statuscode>" + "1" + "</statuscode>"
+ Environment.NewLine + "</Message>"
+ Environment.NewLine + "</Messages>";
// Send back a response.
byte[] httpHeaders = System.Text.Encoding.ASCII.GetBytes("HTTP/1.1 200 OK");
byte[] httpContentType = System.Text.Encoding.ASCII.GetBytes("Content-Type: text/xml");
byte[] httpContentLength = System.Text.Encoding.ASCII.GetBytes("Content - Length: " + xml.Length);
byte[] newLine = System.Text.Encoding.ASCII.GetBytes(Environment.NewLine);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(xml);
stream.Write(httpHeaders, 0, httpHeaders.Length);
stream.Write(httpContentType, 0, httpContentType.Length);
stream.Write(httpContentLength, 0, httpContentLength.Length);
stream.Write(newLine);
stream.Write(msg, 0, msg.Length);
response = xml;
Console.WriteLine("Reply sent from Server: {0}", data);
}
stream.Close();
}
// Loop to receive all the data sent by the client.
// Shutdown and end connection
tcpClient.Close();
//}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
return response;
}
found solution for getting xml response in browser from a tcp background service, instead of using NetworkStream StremReader will do the job for handling passed arguments and StreamWriter will write a response back to client.

POST multipart/form-data contents out of order

I am trying to build a web server using java sockets, everything is fine except when the browser sends POST request with file attached, when the request is received the content of the file is out of order , the file sent was txt file with line numbers when received the line numbers were out of order. is there any way I can avoid this I want ordered data (see pic 99522 is followed by 99712) THANKs
public class Server{
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8080);
while(true) new Thread(new Client(server.accept())).start();
}
}
class Client implements Runnable {
Socket client;
OutputStream os = new FileOutputStream(new File("File12"));
InputStream in;
OutputStream out;
static ArrayList<Socket> clients = new ArrayList<Socket>();
String index;
String response;
Client(Socket client) throws IOException {
String listOfFiles = "<ol>";
this.client = client;
in = client.getInputStream();
out = client.getOutputStream();
clients.add(client);
for (File file : new File(".").listFiles()) if (file.isFile()) listOfFiles += "<li>" + file.getName() + "</li>";
listOfFiles += "</ol>";
index = "<!DOCTYPE html><html><body><h1>" + new Date() + "</h1><hr>"+listOfFiles+"<form id='upload' enctype='multipart/form-data' method='post' action='/upload'><input id='fileupload' multiple name='myfile' type='file' /><input type='submit' value='submit' id='submit' /></form></body></html>";
response = "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length:"+index.length()+"\r\n" +
"\r\n" +
index;
}
public void run() {
try {
String msg = "";
byte buffer[] = new byte[32*1024];
int read = in.read(buffer);
while(read != -1){
msg = new String(buffer);
System.out.println(msg);
if(msg.startsWith("POST")){
System.err.println("RAN IN POST");
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write("Content-Type: text/plain\r\n".getBytes());
out.write(("Content-Length:"+ 4 +"\r\n").getBytes());
out.write("\r\n".getBytes());
out.write("done".getBytes());
}
if(msg.startsWith("GET")){
String path = msg.substring(msg.indexOf("/"), msg.indexOf("HTTP")).trim();
if(path.equals("/")) out.write(response.getBytes());
else {
String fileName = path.substring(1);
fileName = URLDecoder.decode(fileName,"UTF-8");
System.out.println(fileName);
File file = new File(fileName);
if(file.exists()){
System.out.println(file.getName() + " " + file.length());
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write("Accept-Ranges: bytes\r\n".getBytes());
out.write(("Transfer-Encoding: chunked\r\n").getBytes());
out.write("Content-Type: application/octet-stream\r\n".getBytes());
out.write(("Content-Disposition: attachment; filename=\""+file.getName()+"\"\r\n").getBytes());
out.write("\r\n".getBytes());
try{
Files.copy(Paths.get(file.getPath()) , out);
}catch(Exception e){
break;
}
}else System.out.println("file not existes");
}
}
out.flush();
os.close();
read = in.read(buffer);
}
System.err.println("closing scoket");
out.close();
in.close();
client.close();
clients.remove(client);
} catch (IOException e) {
e.printStackTrace();
}
}
}
ALL right found the bug I am not clearing the buffer hence it appears again

Apache commons net FTP clients hangs unpredictably

We tried all the solutions provided in this post (FTP client hangs) but none of them is working. We are using version 3.6 of commons net. Sometimes it hangs while uploading a file, sometimes will checking existence of a directory. Max. file size is around 400 MB. But sometime it hangs even for a small file size < 1KB. Below is the fragment of code:
public boolean uploadData(String inputFilePath, String destinationFolderName) {
if (StringUtil.isNullOrBlank(inputFilePath) || StringUtil.isNullOrBlank(destinationFolderName)) {
LOGGER.error("Invalid parameters to uploadData. Aborting...");
return false;
}
boolean result = false;
FTPSClient ftpClient = getFTPSClient();
if (ftpClient == null) {
logFTPConnectionError();
return false;
}
try {
loginToFTPServer(ftpClient);
result = uploadFileToFTPServer(ftpClient, inputFilePath, destinationFolderName);
} catch (Exception e) {
logErrorUploadingFile(inputFilePath, e);
return false;
} finally {
try {
logoutFromFTPServer(ftpClient);
} catch (Exception e) {
logErrorUploadingFile(inputFilePath, e);
result = false;
}
}
return result;
}
private FTPSClient getFTPSClient() {
FTPSClient ftpClient = null;
try {
ftpClient = new FTPSClient();
LOGGER.debug("Connecting to FTP server...");
ftpClient.setConnectTimeout(connectTimeOut);
ftpClient.connect(server);
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
LOGGER.error("Could not connect to FTP server. Aborting.");
return null;
}
} catch (Exception e) {
LOGGER.error("Could not connect to FTP server.", e);
return null;
}
return ftpClient;
}
private void loginToFTPServer(FTPSClient ftpClient) throws Exception {
ftpClient.setDataTimeout(DATA_TIMEOUT);
ftpClient.login(ftpUserName, ftpPassword);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
LOGGER.debug("FTP Client Buffer Size Before:" + ftpClient.getBufferSize());
ftpClient.setBufferSize(BUFFER_SIZE);
LOGGER.debug("FTP Client Buffer Size After:" + ftpClient.getBufferSize());
ftpClient.execPBSZ(0);
ftpClient.execPROT("P");
ftpClient.setControlKeepAliveTimeout(300);
LOGGER.debug("Logged into FTP server.");
}
private void logoutFromFTPServer(FTPSClient ftpClient) throws Exception {
LOGGER.debug("Logging out from FTP server.");
ftpClient.logout();
ftpClient.disconnect();
LOGGER.debug("FTP server connection closed.");
}
private boolean uploadFileToFTPServer(FTPSClient ftpClient, String inputFilePath, String destinationFolderName) {
boolean result = false;
String remoteLocationFile;
File ftpFile = new File(inputFilePath);
try (InputStream inputStream = new FileInputStream(ftpFile)) {
String fileName = ftpFile.getName();
remoteLocationFile = (destinationFolderName == null || destinationFolderName.isEmpty())
? ftpFile.getName()
: destinationFolderName + File.separator + fileName;
LOGGER.info("Storing file " + ftpFile.getName() + " of size "
+ ftpFile.length() + " in folder " + remoteLocationFile);
result = ftpClient.storeFile(remoteLocationFile, inputStream);
if(result) {
LOGGER.info("Successfully stored file " + ftpFile.getName() + " in folder " + remoteLocationFile);
} else {
LOGGER.error("Unable to store file " + ftpFile.getName() + " in folder " + remoteLocationFile);
}
return result;
} catch (Exception e) {
logErrorUploadingFile(inputFilePath, e);
}
return result;
}
The application is hosted in apache tomcat 8. What could be other causes of this issue and how should we fix them? This is crucial functionality of our application and we may even consider to use alternate API if that is stable. Please suggest.
Adding ftpClient.setSoTimeout(20000); has fixed the issue.
Adding a enterLocalPassiveMode right before the retreiveFile should solve this issue.
You also need to add
ftpClient.setControlKeepAliveTimeout(300);
or Check this code which will resolve the hanging issue

Servlet call hanging when using S3 Java SDK

I have this servlet I call using GWT FileUpload (I don't thing it matters so much that it is GWT):
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
try {
User user = ServerUtil.validateUser(request);
ServletFileUpload upload = new ServletFileUpload();
try {
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String saveFile = item.getName();
InputStream stream = item.openStream();
// Process the input stream
ByteArrayOutputStream out = new ByteArrayOutputStream();
int len;
byte[] buffer = new byte[8192];
while ((len = stream.read(buffer, 0, buffer.length)) != -1) {
out.write(buffer, 0, len);
}
int maxFileSize = 10 * (1024 * 1024); //10 megs max
if (out.size() > maxFileSize) {
throw new RuntimeException("File is > than " + maxFileSize);
}
// save file data
String fileName = user.getUsername() + "_" + new Date().getTime() + "_" + saveFile;
// store to S3
String imageUrl = S3PhotoUtil.storeThumbnailImage(out.toByteArray(), fileName, 100);
// return the url of the file
writer.println(imageUrl);
response.flushBuffer();
return;
}
} catch (RuntimeException e) {
writer.println(("error=" + e.getMessage()).getBytes());
} catch (FileUploadException e) {
writer.println(("error=Could not read file").getBytes());
} catch(IOException e) {
writer.println(("error=Image type not supported!").getBytes());
}
} catch (EIException e) {
e.printStackTrace();
writer.println(("error=Not logged in").getBytes());
}
}
When called the POST hangs, I check on firebug, it looks like it never gets a response. If I debug I see that all instructions are executed without any problem and the method is ran fine. The files are stored on my S3 bucket.
Now if I remove the call relating to the S3 storage it stops hanging, although obviously it doesn't do anything anymore... My conclusion is that there is something in this S3 storage that messes up with my servlet. The code itself is taken from the travel log example application # http://aws.amazon.com/code/1264287584622066
It does say needs tomcat and I'm using jetty... could that be a problem?
Thanks,
Thomas

Weird EOF Exception while trying to download file from GWT application

I am trying to download a file from GWT client. At server side there is a servlet which generates content of file as per request and send it back to the client.
Test Scenarios:
Scenario 1 If I hit url of servlet directly, it always give me desired result without any problems.
Scenario 2
Using GWT client on IE8,I am able to download file without any code changes. However on some other computer as soon as I try to write file content on response output stream, I get EOF exception.
org.mortbay.jetty.EofException
at org.mortbay.jetty.HttpGenerator.flush(HttpGenerator.java:760)
at org.mortbay.jetty.AbstractGenerator$Output.flush(AbstractGenerator.java:566)
at org.mortbay.jetty.HttpConnection$Output.flush(HttpConnection.java:911)
at java.io.BufferedOutputStream.flush(Unknown Source)
atXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.doGet(ServiceDataExporterServlet.java:110)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)Creating input stream....
Code of servlet is as follows:
try
{
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
int bytesWritten=0;
while ((length = data.read(buffer)) > 0) {
bytesWritten+=length;
output.write(buffer, 0, length);
}
output.flush() // At this point I am facing EOF exception.
where data is inputStream
Via means of bytesWritten variable I have confirmed that in all the three scenarios content has been written in the same way in output stream. But not sure why it is not working in some computers.
Any points will be highly appereciated.
I do something like this to download files with GWT
In the server side:
public static void sendFileToClient(String path, String filename,
int contentLen, HttpServletRequest request,
HttpServletResponse response) throws UnsupportedEncodingException
{
String ua = request.getHeader("User-Agent").toLowerCase();
boolean isIE = ((ua.indexOf("msie 6.0") != -1) || (ua
.indexOf("msie 7.0") != -1)) ? true : false;
String encName = URLEncoder.encode(filename, "UTF-8");
// Derived from Squirrel Mail and from
// http://www.jspwiki.org/wiki/BugSSLAndIENoCacheBug
if (request.isSecure())
{
response.addHeader("Pragma", "no-cache");
response.addHeader("Expires", "-1");
response.addHeader("Cache-Control", "no-cache");
}
else
{
response.addHeader("Cache-Control", "private");
response.addHeader("Pragma", "public");
}
if (isIE)
{
response.addHeader("Content-Disposition", "attachment; filename=\"" + encName + "\"");
response.addHeader("Connection", "close");
response.setContentType("application/force-download; name=\"" + encName + "\"");
}
else
{
response.addHeader("Content-Disposition", "attachment; filename=\""
+ encName + "\"");
response.setContentType("application/octet-stream; name=\""
+ encName + "\"");
if (contentLen > 0)
response.setContentLength(contentLen);
}
try
{
FileInputStream zipIn = new FileInputStream(new File(path));
ServletOutputStream out = response.getOutputStream();
response.setBufferSize(8 * 1024);
int bufSize = response.getBufferSize();
byte[] buffer = new byte[bufSize];
BufferedInputStream bis = new BufferedInputStream(zipIn, bufSize);
int count;
while ((count = bis.read(buffer, 0, bufSize)) != -1)
{
out.write(buffer, 0, count);
}
bis.close();
zipIn.close();
out.flush();
out.close();
}
catch (FileNotFoundException e)
{
System.out.println("File not found");
}
catch (IOException e)
{
System.out.println("IO error");
}
}
I have a servlet that expects for an id and then I get the related file path and I serve it to the browser with the above code.
In the client side:
public class DownloadIFrame extends Frame implements LoadHandler,
HasLoadHandlers
{
public static final String DOWNLOAD_FRAME = "__gwt_downloadFrame";
public DownloadIFrame(String url)
{
super();
setSize("0px", "0px");
setVisible(false);
RootPanel rp = RootPanel.get(DOWNLOAD_FRAME);
if (rp != null)
{
addLoadHandler(this);
rp.add(this);
setUrl(url);
}
else
openURLInNewWindow(url);
}
native void openURLInNewWindow(String url) /*-{
$wnd.open(url);
}-*/;
public HandlerRegistration addLoadHandler(LoadHandler handler)
{
return addHandler(handler, LoadEvent.getType());
}
public void onLoad(LoadEvent event)
{
}
}
In you hosted page add this Iframe
<iframe src="javascript:''" id="__gwt_downloadFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
Then to download a file put something like this:
btnDownload.addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent arg0)
{
String url = GWT.getModuleBaseURL()
+ "/downloadServlet?id=[FILE_ID]";
new DownloadIFrame(url);
}
});
I hope this helps you.
Happy coding!
It happens also if the OutputStream flushes after InputStream was closed, like this:
myInputStream.close();
myOutputStream.flush();
myOutputStream.close();
it should be like:
myOutputStream.flush();
myInputStream.close();
myOutputStream.close();
Hope it helps :-)