I hava a socket server is written in Java and the client is written in C#.
If I use the InputStream in a socket server, I can get the request from the Client. My code as below:
InputStream myIN = sock.getInputStream();
byte[] b = new byte[10];
int revByte = myIN.read(b);
but if I use the ObjectInputStream in the socket server, I can not receive any request from the Client.The exception is: "java.io.StreamCorruptedException: invalid stream header"
My code as below:
in = new ObjectInputStream( sock.getInputStream() );
Object value = in.readObject();
So, my question is: can C# client work with ObjectInputStream in Java via socket?
Any helping will be appreciate.Thanks so much, Dan
ObjectInputStream expects a data stream containing serialized representations of java objects... theoretically c# could encode it's objects in java's serialization format, but it wouldn't be pretty.
jspcal is right: Maybe with these classes?
http://mediakey.dk/~cc/java-and-c-client-server-socket-programming/
Java Server
try
{
ServerSocket ss = new ServerSocket(1800);
Socket s = ss.accept();
System.out.println("Client Accepted");
BufferedReader br = new BufferedReader(new
InputStreamReader(s.getInputStream()));
System.out.println(br.readLine());
PrintWriter wr = new PrintWriter(new OutputStreamWriter(s.getOutputStream()),true);
wr.println("Welcome to Socket Programming");
}
catch(Exception e){ System.out.println(e); }
C# Client:
try
{
TcpClient tc = new TcpClient("server",1800);// in the place of server, enter your java server's hostname or Ip
Console.WriteLine("Server invoked");
NetworkStream ns = tc.GetStream();
StreamWriter sw = new StreamWriter(ns);
sw.WriteLine("My name is Pramod.A");
sw.Flush();
StreamReader sr = new StreamReader(ns);
Console.WriteLine(sr.ReadLine());
}
catch(Exception e){ Console.WriteLine(e); }
Related
I am developing a REST client using JBOSS app server and RESTEasy 2.3.6. I've included the following line at the beginning of my code:
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
Here's the rest of the snippet:
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(host, port, AuthScope.ANY_REALM), new UsernamePasswordCredentials(userid,password));
ClientExecutor executor = createAuthenticatingExecutor(httpclient, host, port);
String uriTemplate = "http://myhost:8080/webapp/rest/MySearch";
ClientRequest request = new ClientRequest(uriTemplate, executor);
request.accept("application/json").queryParameter("query", searchArg);
ClientResponse<SearchResponse> response = null;
List<MyClass> values = null;
try
{
response = request.get(SearchResponse.class);
if (response.getResponseStatus().getStatusCode() != 200)
{
throw new Exception("REST GET failed");
}
SearchResponse searchResp = response.getEntity();
values = searchResp.getValue();
}
catch (ClientResponseFailure e)
{
log.error("REST call failed", e);
}
finally
{
response.releaseConnection();
}
private ClientExecutor createAuthenticatingExecutor(DefaultHttpClient client, String server, int port)
{
// Create AuthCache instance
AuthCache authCache = new BasicAuthCache();
// Generate BASIC scheme object and add it to the local auth cache
BasicScheme basicAuth = new BasicScheme();
HttpHost targetHost = new HttpHost(server, port);
authCache.put(targetHost, basicAuth);
// Add AuthCache to the execution context
BasicHttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.AUTH_CACHE, authCache);
// Create ClientExecutor.
ApacheHttpClient4Executor executor = new ApacheHttpClient4Executor(client, localContext);
return executor;
}
The above is a fairly simple client that employs the ClientRequest/ClientResponse<T> technique. This is documented here. The above code does work (only left out some trivial variable declarations like host and port). It is unclear to me from the JBOSS documentation as to whether I need to run RegisterBuiltin.register first. If I remove the line completely - my code still functions. Do I really need to include the register method call given the approach I have taken? The Docs say I need to run this once per VM. Secondly, if I am required to call it, is it safe to call more than one time in the same VM?
NOTE: I do understand there are newer versions of RESTEasy for JBOSS, we are not there yet.
I am deploying my application in Tandem System (Unix environment). I am trying to connect to other application using TCP. I have a IP adress and Port number. from client (my application), I am writing data, looks like it's working (Not getting any Exception) but while reading data, I am getting ReadTimeOutException. Below is my program, I will appreciate your help. There is the same application which is return is C++ it's working fine with the same IP Address and Port number
Socket clientSocket = new Socket();
clientSocket.setKeepAlive(true);
clientSocket.setReuseAddress(true);
clientSocket.setTcpNoDelay(true);
clientSocket.setSoTimeout(120000);
clientSocket.setSendBufferSize(65535);
clientSocket.connect(new InetSocketAddress("Server IP", "Port Number"), 1000);
OutputStream outstream = clientSocket.getOutputStream();
outstream .writeInt(msgLen);
dout.write(msg, 0, msgLen);
dout.flush();
DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
int len = din.readInt();
data = new byte[len];
dis .readFully(data);
Its Throwing an Error while reading it.
Timeout while attempting to establish socket connection.
java.net.SocketTimeoutException: Read timed out
===========================
Socket clientSocket = new Socket();
clientSocket.setKeepAlive(true);
clientSocket.setReuseAddress(true);
clientSocket.setTcpNoDelay(true);
clientSocket.setSoTimeout(120000); // Should wait 3 minutes before throwing time out exception - Actually throwing after 2 minutes
clientSocket.setSendBufferSize(65535);
InputStream in= new ObjectInputStream(socket.getInputStream());
OutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.write(byteArray);
out.flush();
// Receive the same string back from the server
int totalBytesRcvd = 0; // Total bytes received so far
int bytesRcvd; // Bytes received in last read
while (totalBytesRcvd < byteArray.length) {
if ((bytesRcvd = in.read(byteArray, totalBytesRcvd,
byteArray.length - totalBytesRcvd)) == -1)
throw new SocketException("Connection close prematurely");
totalBytesRcvd += bytesRcvd;
}
clientSocket .close(); // Close the socket and its streams
Please help me with this problem, I am stuck on this since last week.
Thank you!!!!
It isn't throwing that exception 'while attempting to establish the connection'. It is throwing it at some read call, almost certainly inside the constructor for ObjectInputStream. You should have included the stack trace in your question.
You need to create the ObjectOutputStream before the ObjectInputStream.
12000 milliseconds is two minutes, not three.
You should use readFully() at the client, just like you're doing in the server.
i have a trouble with my socket programming code.
when i use below:
var ipaddress = IPAddress.Parse("192.168.1.100");
IPAddress add = new IPAddress(ipaddress.GetAddressBytes());
TcpListener tcpListener = null;
tcpListener = new TcpListener(add, 53);
tcpListener.Start();
Console.WriteLine("Waiting for a connection...");
while (true)
{
Thread.Sleep(10);
TcpClient tcpClient = tcpListener.AcceptTcpClient();
//Read the data stream from the client.
byte[] bytes = new byte[512];
NetworkStream stream = tcpClient.GetStream();
stream.Read(bytes, 0, bytes.Length);
SocketHelper helper = new SocketHelper();
helper.processMsg(tcpClient, stream, bytes);
}
i receive this error:
Additional information: Only one usage of each socket address (protocol/network address/port) is normally permitted
but i changed my cod to below :
static Socket sktListener;
var ipaddress = IPAddress.Parse("192.168.1.100");
IPAddress add = new IPAddress(ipaddress.GetAddressBytes());
sktListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint(add, 53);
sktListener.Connect(ipLocal);
if (sktListener.Connected)
{
byte[] bytes = new byte[512];
int i = sktListener.Receive(bytes);
Console.WriteLine(Encoding.UTF8.GetString(bytes));
}
but it dose not any work. and stop on this line
int i = sktListener.Receive(bytes);
IPAddress.Parse() returns a new IPAddress object, you do not need to create a second IPAddress object from the first object's bytes:
IPAddress add = IPAddress.Parse("192.168.1.100");
Regarding the usage error in the first code, it means 192.168.1.100:53 is already in use by another socket.
Your second code is not creating a server, it is creating a client that connects to a server. Assuming these codes are meant to work together, then it makes sense why Receive() is blocking - your client is expecting to receive data that your server is not sending. Your server code is expecting a new client to send data, but your client is not sending anything.
I want to do a POST request to an HTTP Servlet I wrote myself. Good case (HTTP response Code 200) always works fine by using URL.openConnection() method. But when I receive a desired error response code (e.g. 400) then I thought I have to use HttpUrlConnection.getErrorStream(). But the ErrorStream object is null though I am sending data back from the servlet in error case (I want to evaluate this data to generate error messages).
This is what my code looks like:
HttpURLConnection con = null;
try {
//Generating request String
String request = "request="+URLEncoder.encode(xmlGenerator.getStringFromDocument(xmlGenerator.generateConnectRequest(1234)),"UTF-8");
//Receiving HttpUrlConnection (DoOutput = true; RequestMethod is set to "POST")
con = openConnection();
if (con != null){
PrintWriter pw = new PrintWriter(con.getOutputStream());
pw.println(request);
pw.flush();
pw.close();
InputStream errorstream = con.getErrorStream();
BufferedReader br = null;
if (errorstream == null){
InputStream inputstream = con.getInputStream();
br = new BufferedReader(new InputStreamReader(inputstream));
}else{
br = new BufferedReader(new InputStreamReader(errorstream));
}
String response = "";
String nachricht;
while ((nachricht = br.readLine()) != null){
response += nachricht;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
So my question is, why returns getErrorStream() null though status code is 400 (I can see it in the IOException that is thrown when it calls con.getInputStream())
Thanks
From the java documentation on getErrorStream():
Returns the error stream if the connection failed but the server sent useful data nonetheless. The typical example is when an HTTP server responds with a 404, which will cause a FileNotFoundException to be thrown in connect, but the server sent an HTML help page with suggestions as to what to do.
This method will not cause a connection to be initiated. If the connection was not connected, or if the server did not have an error while connecting or if the server had an error but no error data was sent, this method will return null. This is the default.
So if you didn't get to the server (bad url for example) or the server didn't send anything in the response, getErrorStream() will return null.
InputStream inputStream = null;
try {
inputStream = connection.getInputStream();
} catch(IOException exception) {
inputStream = connection.getErrorStream();
}
It is like when you set response header status code as anything beyond 200, the connection object is reset. it will generate SocketTimeoutException while getting the inputstream but when it comes in the catch it gives you the inputstream anyway, what you are expecting.
Digging a little bit into JDK code, I finally find the reason. HttpURLConnection#getErrorStream() returns null when receiving a 401 or 407, not because the noop implementation in the abstract class, but because HttpURLConnection closes/clears the connection immediately if it sees a 401/407 when in streaming mode(i.e., POST). See the source of the concrete implementation of HttpURLConnection: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/net/www/protocol/http/HttpURLConnection.java#1079
That said, when you catch an IOException when calling getInputStream(), the connection to server is already closed and the underlining socket is cleared, so you would always get null when calling getErrorStream().
The other options many have suggested is to check the status code before calling getInputStream or getErrorStream. This won't for 401 and 407 either because the internal errorStream is only set when you call getInputStream, i.e., it's a basically a copy of the inputStream when status code != 200. But again when you call getInputStream, the connection will be closed.
Put the statement conn.setAllowUserInteraction(true); before execute the request and the connection will not be closed, even receiving 401 status.
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setAllowUserInteraction(true); // <<<--- ### HERE
//do something
conn.connect();
boolean isError = (conn.getResponseCode() >= 400);
InputSteam is = isError ? con.getErrorStream() : con.getInputStream();
As suggested in the Android documentation:
String responseString;
try {
responseString = readInputStream(con.getInputStream());
} catch (final IOException e) {
// This means that an error occurred, read the error from the ErrorStream
try {
responseString = readInputStream(con.getErrorStream());
} catch (IOException e1) {
throw new IllegalStateException("Unable to read error body.", e);
}
}
private String readInputStream(final InputStream inputStream) throws IOException {
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
final StringBuilder responseString = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
responseString.append(line);
}
bufferedReader.close();
return responseString.toString();
}
I have integrated JasperReports on my NetBeans platform and I am able to generate reports using the following code:
Map<String, Object> params = new HashMap<String, Object>();
Connection conn = DriverManager.getConnection("databaseUrl", "userid", "password");
JasperReport jasperReport = JasperCompileManager.compileReport(reportSource);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, conn);
JasperExportManager.exportReportToHtmlFile(jasperPrint, reportDest);
JasperViewer.viewReport(jasperPrint);
This stuff works perfect.
But not I'm trying to integrate JasperReports with GWT. I have my server as GlassFish server.
I am getting the Connection object using the followind code:
public static Connection getConnection() {
try {
String JNDI = "JNDI name";
InitialContext initCtx = new InitialContext();
javax.sql.DataSource ds = (javax.sql.DataSource) initCtx.lookup(JNDI);
Connection conn = (Connection) ds.getConnection();
return conn;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
and then
Map<String, Object> params = new HashMap<String, Object>();
JasperReport jasperReport = JasperCompileManager.compileReport(reportSource);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, getConnection());
JasperExportManager.exportReportToHtmlFile(jasperPrint, reportDest);
JasperViewer.viewReport(jasperPrint);
but i always get an Error. Here is a stacktrace:
com.google.gwt.user.server.rpc.UnexpectedException:
Service method 'public abstract java.lang.Boolean com.client.service.GenerateReport()'
threw an unexpected exception: java.lang.NoSuchMethodError:
net.sf.jasperreports.engine.fonts.SimpleFontFamily.setExportFonts(Ljava/util/Map);
I am implementing this on Server. I am having RPC calls to get this method to work when a button is clicked.
Can you please help me how to work on this. (That is to integrate JasperReports with GWT).
I would highly appreciate any explanation with some code as i am just a beginner.
Thanks
Without the aid of error messages, I would say that you have Google App Engine enabled in your eclipse project preferences. GAE does NOT allow you to write to the file system, or make calls to a database.
Try disabling GAE, and things should work fine.