I read other SO questions about this problem and nothing solve my problem so I think this post is not a duplicate.
I want to send a Unicode string from android client socket to a server socket But I receive all Unicode character as question marks from server (I use a c# server on windows). I use WireShark to monitor network and it show all Unicode character as dots. This is my send code:
String msg = "تست سوکت";
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(msg);
out.flush();
Some stackOverFlow question says adding charSetEncoder to OutputStreamWriter constractor can solve this but that's not worked for me and the result was the same:
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream(),
Charset.forName("UTF-8").newEncoder())),
true);
// Or
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream(),
"UTF-8")),
true);
After that I try to send byte array as string, But that send nothing to server:
byte[] byteArray = msg.getBytes(Charset.forName("UTF-8"));
out.println(byteArray.toString() + "\n");
Your Java code is correct.
That Wireshark is not showing unicode characters is assumable a limitation of Wireshark.
Therefore the receiving C# program must be the problem. Are you sure that this program expects a stream of UTF-8 characters?
"Unicode" on Windows and C# usually means UTF-16, not UTF-8.
Related
I'm trying to send a message from a computer and read it from another using java socket. The problem is that the message received by the server is something unencoded represented by two question marks inside a diamond.
To read and write I use the following objects:
PrintWriter out = new PrintWriter(new OutputStreamWriter( socket.getOutputStream(), "UTF-8"), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")));
And the methods:
out.println("OK");
in.readLine();
Use DataInputStream and DataOutputStream to read/write the socket. These have readUTF() and writeUTF() methods which will send Strings properly.
I am creating a simple Client-Server application and facing some weird behaviour when passing messages through a Socket: When the Client writes to the server, the message is passed correctly, however when the server sends a response, whichever value is sent through the socket seems to get duplicated...
Here is a sample code of what the server does:
.
.
.
public void respond(Socket socket)
{
try
{
InputStreamReader inStream = new InputStreamReader( socket.getInputStream() );
PrintWriter outStream = new PrintWriter(
new OutputStreamWriter( socket.getOutputStream(), "UTF-16" ) );
outStream.write("Message received\n");
outStream.flush();
.
.
.
}
catch (Exception e) { /* Do something */ }
}
.
.
.
Server and Client are currently running on the same machine.
Furthermore, encoding seems to be no issue when writing from client to server, but it is when writing from server to client: If I specify any other (or no) encoding than UTF-16 for the OutputStreamWriter, the Client won't be able to parse the message correctly.
Does any of you guys have an idea why that might be?
The character encoding on each end of the conversation needs to be the same: the Charset used for encoding by InputStreamReader at the client must match that used by the OutputStreamWriter at the server (and vice-versa).
If you don't specify one, it is going to use the JVM's default.
When you didn't provided your client's code, the fact that the server is using the default Charset to read and UTF-16 to write makes me think there is a potential mismatch.
I am trying to create a proxy server.
I want to read the websites byte by byte so that I can display images and all other stuff. I tried readLine but I can't display images. Do you have any suggestions how I can change my code and send all data with DataOutputStream object to browser ?
try{
Socket s = new Socket(InetAddress.getByName(req.hostname), 80);
String file = parcala(req.url);
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader dis = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter socketOut = new PrintWriter(s.getOutputStream());
socketOut.print("GET "+ req.url + "\n\n");
//socketOut.print("Host: "+req.hostname);
socketOut.flush();
String line;
while ((line = dis.readLine()) != null){
System.out.println(line);
}
}
catch (Exception e){}
}
Edited Part
This is what I should have to do. I can block banned web sites but can't allow other web sites in my program.
In the filter program, you will open a TCP socket at the specified port and wait for connections. If a
request comes (i.e. the client types a URL to access a web site), the application will process it to
decide whether access is allowed or not and then, using the same socket, it will send the reply back
to the client. After the client opened her connection to WebPolice (and her request has been checked
and is allowed), the real web page needs to be shown to the client. Therefore, since the user already gave her request, now it is WebPolice’s turn to forward the request so that the user can get the web page. Thus, WebPolice acts as a client and requests the web page. This means you need to open a connection to the web server (without closing the connection to the user), forward the request over this connection, get the reply and forward it back to the client. You will use threads to handle multiple connections (at the same time and/or at different times).
I don't know what exactly you're trying to do, but crafting an HTTP request and reading its response incorporates somewhat more than you have done here. Readline won't work on binary data anyway.
You can take a look at the URLConnection class (stolen here):
URL oracle = new URL("http://www.oracle.com/");
URLConnection yc = oracle.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
Then you can read textual or binary data from the in object.
Read line will treat the line read as a String, so unless you want to mess around with conversions over to bytes, I wouldn't recommend that.
I would just read bytes until you can't read anymore, then write them out to a file, this should allow you to grab the images, keeping file headers intact which can be important when dealing with files other than text.
Hope this helps.
Instead of using BufferedReader you can try to use InputStream.
It has several methods for reading bytes.
http://docs.oracle.com/javase/6/docs/api/java/io/InputStream.html
My server code is as follow:
writer = new PrintWriter(s.getOutputStream());
writer.flush();
writer.print("HTTP/1.1 200 OK\r\n");
writer.print("Content-Length: " + len + "\r\n");
writer.print("Content-Type: "+"application/soap+xml;charset=utf-8"+"\r\n\r\n");
writer.print(response);
writer.close();
The variable response is SOAP+XML. I am adding the HTTP headers needed to send it over and it works in some cases but in most cases my client(SOAPUI) just waits for the response which doesn't get produced. When I close the client I don't see any error on the server side.
Any help is appreciated. Thanks.
From Socket.getOutputStream():
"...Closing the returned OutputStream will close the associated socket....".
Closing the PrintWriter will close the OutputStream which in turn will close the socket. Just flush the PrintWriter, don't close it.
I'm trying to read from a URL, and then print the result.
BufferedReader in = new BufferedReader(
new InputStreamReader(new URL("http://somesite.com/").openStream(), "UTF-8"));
String s = "";
while ((s=in.readLine())!=null) System.out.println(s);
in.close();
It works great most of the time, and prints the website's source.
However, my problem is, on specific websites, instead of the source code, it will print out gibberish, such as symbols and other unusual characters.
Is there some property that varies from website to website that would affect how it is read? The page loads just fine in Firefox, and I can view the source there with no problem. If firefox can access the source, I should be able to as well; I'm just not sure why it isn't working...
EDIT: added "UTF-8" to InputStreamReader. All of the strange characters are now question marks...still not working...
So after much searching I found the answer to this. The xml is read as gibberish because it is Gzip compressed. The way to read this is by using the GZIPInputStream. This is because the XML is compressed differently.
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Accept-Encoding", "gzip");
InputStreamReader in = new InputStreamReader (new GZIPInputStream(connection.getInputStream()));
String str;
while (true) {
int ch = in.read();
if (ch==-1) {
break;
}
You're probably running into a character encoding issue.
There should be an HTTP header like the following in the response:
Content-Type: text/html; charset=UTF-8
Try using telnet to diagnose what's coming over the wire. It may not be textual data. For example, what happens when yo do this?
telnet somesite.com 80
GET / HTTP/1.0
Host: somesite.com
(two carriage returns required after last line)
This should allow you to see the headers and content coming in and should give you a better clue as to what's going on.
I had the same issue until I used HttpURLConnection with setChunkedStreamingMode set.
HttpURLConnection connection = (HttpURLConnection)serverAddress.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setReadTimeout(2000);
connection.setChunkedStreamingMode(0);
connection.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = "";
while ((line = rd.readLine()) != null)
{
sb.append(line);
}
System.out.println(sb.toString());