Socket implementation with ObjectInputStream - can't read object - sockets

For a Java class I am taking, I need to use sockets to pass data back and forth between client and server. While I can get examples to work passing string data, I need to be able to pass custom class objects (i.e. a product) and lists of these objects back and forth. I cannot get the server piece to successfully read the input. I tried to create a simple example of my code to see if anyone can pinpoint the issue. I do understand that I don't have the code complete, but I cannot even get the server to read the object the the class is writing to the stream (in this case, I am writing a string just in an attempt to get it to work, but need to read/write objects). Here is my code. I have spent hours and hours trying this and researching other people's questions and answere, but still can't get this to work.
Here the sample code:
simple server:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class simpleServer {
public static final int PORT_NO = 8888;
static ObjectInputStream serverReader = null;
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket serverSocket = new ServerSocket(PORT_NO);
System.out.println("... server is accepting request");
Object myObject = null;
while (true) {
Socket socket = serverSocket.accept();
System.out.println("creating reader");
ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream());
serverReader = new ObjectInputStream(socket.getInputStream());
System.out.println("created reader");
try {
System.out.println("try to read");
myObject = serverReader.readObject();
System.out.println("read it");
System.out.println(myObject);
if (myObject != null) objOut.writeUTF("Got something");
else objOut.writeUTF("got nothing");
if ("quit".equals(myObject.toString())) serverSocket.close();
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
System.out.println("cath for readobject");
}
catch (Exception e) {
System.out.println("other error");
System.out.println(e.getMessage());
}
}
}
}
simple client:
public static void main(String[] args) {
Socket socket;
try {
socket = new Socket("localhost", ProductDBServer.PORT_NO);
ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objIn = new ObjectInputStream(socket.getInputStream());
objOut.writeUTF("loadProductsFromDisk");
objOut.flush();
String myString = objIn.toString();
//System.out.println(myString);
if (!"quit".equals(objIn.toString().trim())) {
//System.out.println("reading line 1");
String line;
try {
line = (String)objIn.readObject();
//System.out.println("line is " + line);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
objIn.close();
//System.out.println("result: " + line);
}
System.out.println("closing socket");
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
System.out.println("Unknownhostexception");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("ioexception");
e.printStackTrace();
}
}
The code appears to run to the point on the server side where it trys to read the object I sent, and then dies. Can someone see what I am doing wrong? This seems to be such a simple thing to do, and yet I can't seem to get it to work. Thanks for any help!

To write objects to an ObjectOutputStream you need to call writeObject().
Not writeUTF().
To read objects from an ObjectInputStream you need to call readObject().
Not toString().

See in your code:
// Simple Client
objOut.writeUTF("loadProductsFromDisk"); // Line 8
You are sending the String "loadProductsFromDisk" in the UTF-8 format towards the server side.
So in order to receive it and read it over the server side, you will need something like this:
String clientReq = serverReader.readUTF();
Where, serverReader is your ObjectInputStream object.
Otherwise, if you wish to send and receive objects you must use the
writeObject() & readObject() methods respectively.

Related

Sending buffered image over socket from client to server

I am trying to send the images captured from client to server,images are captured using robot class and writing to client socket. In server i am reading the buffered image and writing into server local storage area.I want client capture the screenshots at a regular interval and send to server.server reads the images and stores in its repository.
public class ServerDemo {
public static void main(String[] args) {
try {
ServerSocket serversocket=new ServerSocket(6666);
System.out.println("server listening..........");
while(true)
{
Thread ts=new Thread( new ServerThread(serversocket.accept()));
ts.start();
System.out.println("server thread started.........");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ServerThread.java
public class ServerThread implements Runnable {
Socket s;
BufferedImage img = null;
String savelocation="d:\\Screenshot\\";
public ServerThread(Socket server) {
this.s=server;
}
#Override
public void run() {
try {
System.out.println("trying to read Image");
img = ImageIO.read(s.getInputStream());
System.out.println("Image Reading successful.....");
} catch (IOException e) {
System.out.println(e);
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File save_path=new File(savelocation);
save_path.mkdirs();
try {
ImageIO.write(img, "JPG",new File(savelocation+"img-"+System.currentTimeMillis()+".jpg"));
System.out.println("Image writing successful......");
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(e);
e.printStackTrace();
}
}
}
ClientDemo.java
public class ClientDemo {
public static void main(String[] args) throws InterruptedException {
try {
Socket client=new Socket("localhost", 6666);
while(true)
{
System.out.println("Hello");
Thread th=new Thread(new ClientThread(client));
th.start();
System.out.println("Thread started........");
th.sleep(1000*60);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ClientThread.java
public class ClientThread implements Runnable{
Socket c;
public ClientThread(Socket client) {
this.c=client;
}
#Override
public void run() {
try {
System.out.println("client");
//while(true){
Dimension size=Toolkit.getDefaultToolkit().getScreenSize();
Robot robot=new Robot();
BufferedImage img=robot.createScreenCapture(new Rectangle(size));
System.out.println("Going to capture client screen");
ImageIO.write(img, "JPG", c.getOutputStream());
System.out.println("Image capture from client success...!");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Server Console
server listening..........
server thread started.........
trying to read Image
Image Reading successful.....
Image writing successful......
Client console
Hello
Thread started........
client
Going to capture client screen
Image capture from client success...!
Hello
Thread started........
client
Going to capture client screen
Hello
Thread started........
client
Going to capture client screen
Repeat like this.This code works perfectly for first time after that it fails.Each time runs it capture the images only once.What change i have to make to capture and write the images at regular intervals...Please help me
Try this in ClientDemo.java
while(true)
{
System.out.println("Hello");
Socket client=new Socket("localhost", 6666);
Thread th=new Thread(new ClientThread(client));
th.start();
System.out.println("Thread started........");
th.sleep(1000*60);
}
And make sure that you close the client socket once the thread(ClientThread.java) is completed may be in finally block or at the end of code.
You don't need ImageIO for the server end of this. Just send and receive bytes:
while ((count = in.read(buffer()) > 0)
{
out.write(buffer, 0, count);
}
I see the problem is in the server. The first time it accepts a connection from the client,Thread ts=new Thread( new ServerThread(serversocket.accept())); but the client only connects once Socket client=new Socket("localhost", 6666); When the first transfer is completed the server stay again in the accept waiting for the client to make the connect which never happen again. Therefore either you should issue only one accept and use that socket for every transfer or close both sockets, at the client and server, and make the accept/connect again.

Java 7 doesn't throw BindException when binding an already used port using ServerSocket

I'm experimenting on ServerSocket in Java on Windows 7 x64.
I wrote a little program that host a HTTP server on port 8080 and only returns a static HTML response that contains the toString() of the class loader.
What I did in the program mainly:
Create a ServerSocket
call setReuseAddress(false) on the serverSocket
Bind port 8080 to this socket
Use a forever loop to accept socket and give response
First I tried with JRE 1.6.0_23 and everything is great: first instance launched and responds normally, second instance cannot be launched since exception is thrown:
Exception in thread "main" java.net.BindException: Address already in use: JVM_Bind
Unexpected thing happens when I tried with JRE 1.7.0_5: both instance can be launched successfully but only the first instance gives responses. After the first instance is kill, the second instance then starts to responds.
Am I doing anything wrong or is this a bug of JRE 7?
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServerSocket {
private static final String HEADER = "HTTP/1.1 200 OK\r\n" + "Content-type: text/html\r\n"
+ "Connection: close\r\n" + "\r\n";
private static final int PORT = 8080;
private static void handle(Socket socket) {
System.out.println(socket.getInetAddress() + ":" + socket.getPort());
StringBuilder buffer = new StringBuilder();
buffer.append(HEADER);
buffer.append(TestServerSocket.class.getClassLoader());
try {
socket.getOutputStream().write(buffer.toString().getBytes());
} catch (IOException e) {
} finally {
try {
socket.close();
} catch (IOException e) {
}
}
}
public static void main(String[] args) throws IOException {
int port;
try {
port = Integer.parseInt(args[0]);
} catch (Exception e) {
port = PORT;
}
final ServerSocket server = new ServerSocket();
server.setReuseAddress(false);
server.bind(new InetSocketAddress(port));
// Terminator thread, stop when Ctrl-D is entered
new Thread() {
public void run() {
try {
while (System.in.read() != 4);
} catch (IOException e) {
e.printStackTrace();
}
try {
server.close();
} catch (IOException e) {
}
System.exit(0);
}
}.start();
System.out.println("Listening on: " + port);
Socket client = null;
while (true) {
try {
client = server.accept();
handle(client);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
To Isolate the problem, I would recommend that you run the following test code.
Apache HttpCore basic server. It's standard API and uses ServerSocket in this particular example, so there is a very small chance that it would fail on your environment ( java 7).
In case it fails you will know for sure problem is not with your code. Meanwhile I will try your code on JDK 7 on my work-machine and will update.

How can I marshal Objects from a Socket without closing it? (JAXB Marshaling from Inputstream via Socket)

I have tried in many different ways to send my xml document over a socket connection between a server and a client without closing the socket after sending (keep the outputstream open, for sending another document). I have found several sites who claimed that it should work, so I tried it in all the ways they sugested, but I did not found a way which works.
(that describes the same what I would like to do: http://jaxb.java.net/guide/Designing_a_client_server_protocol_in_XML.html)
The follwing code works perfectly if I am closing the socket after sending (#code marsh.marshal(element, xsw);), but it stucks on unmarshaling on the server side, if I try to keep the socket open.
Client Side....
public void sendMessage(String message){
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library");
Marshaller marsh = jaxbContext.createMarshaller();
marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marsh.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.org/WizardShema WizardsSchema.xsd");
ObjectFactory of = new ObjectFactory();
// the Dataset is the root element of the xml document
Dataset set = new Dataset("CONN01", "CONTR", "MCL01#localhost", "SV01#localhost:32000");
CommandSet cmdSet = new CommandSet();
Command cmd = new Command();
cmd.setFunctionName("RegisterAs");
Param p = new Param();
p.setString("RemoteClient");
cmd.addParameter(p);
cmdSet.addCommand(cmd);
set.setInstruction(cmdSet);
// creates a valid xml dataset, with startDocument, startElement...
JAXBElement<Dataset> element = of.createData(set);
XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(mOOS);
marsh.marshal(element, xsw);
xsw.flush();
} catch (JAXBException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
SERVER Side....
private void handleMessage() {
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library") ;
Unmarshaller um = jaxbContext.createUnmarshaller();
XMLInputFactory xmlif = XMLInputFactory.newInstance();
// XMLEventReader xmlr = xmlif.createXMLEventReader(mOIS);
XMLStreamReader xmlr = xmlif.createXMLStreamReader(mOIS, "UTF8");
// move to the root element and check its name.
xmlr.nextTag();
System.out.println("TagName:" + xmlr.getLocalName());
xmlr.require(START_ELEMENT, null, "Data");
JAXBElement<Dataset> obj = um.unmarshal(xmlr, Dataset.class);
Dataset set = obj.getValue();
System.out.println("ID:"+ set.getID());
} catch (JAXBException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}

Java socket programming problem

Hey,
I am trying to run this socket programming code.
This is the code on the server side -
package sockettest;
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(139);
}
catch (IOException e)
{
System.err.println("not able to listen on port");
System.exit(1);
}
Socket clientSocket = null;
try
{
clientSocket = serverSocket.accept();
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); // Out is Outputstream is used to write to the Client .
BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); // in is used to read the Client's input.
String inputLine, outputLine;
out.println("Hey! . Who are you?"); // Writes to client as "Hey! . Who are you?"
while ((inputLine = in.readLine()) != null)
{
// Reads the input from the Client. if it is "bye" the program ends.
if (inputLine.equalsIgnoreCase("Bye"))
{
out.println("Bye");
break;
}
else
{
out.println("Hello Mr. " + inputLine);
}
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
This is the code running on the client side -
import java.io.*;
import java.net.*;
public class Client
{
public static void main(String[] args) throws IOException {
Socket kkSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try
{
kkSocket = new Socket("192.168.2.3", 139);
out = new PrintWriter(kkSocket.getOutputStream(), true); // Out may be used to write to server from the client
in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream())); // in will be used to read the lines sent by the Server.
}
catch (UnknownHostException e)
{
System.err.println("Unidentified host.");
System.exit(1);
}
catch (IOException e)
{
System.err.println("Couldn't get I/O for the connection to.");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromClient;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye"))
break;
fromClient = stdIn.readLine();
if (fromClient != null) {
System.out.println("Client: " + fromClient);
out.println(fromClient);
}
}
out.close();
in.close();
stdIn.close();
kkSocket.close();
}
}
I'm running the codes on eclipse in both the client and the server side. Using netstat -an command in cmd prompt, i can see that a connection has been established between the client and the server but i cannot communicate and eclipse is not showing any output too. What seems to be wrong??
You haven't told us what the problem is. However, from a cursory glance at your code, I would advise against listening on port 139 as this is already used by NetBios under Windows and may cause a conflict.
also your Server code is missing
the initialization of inputLine,
e.g
String inputline = "";
before the while loop
keep in mind that Socket's are blocked if you read or write...
your client is reading all the time because it waits for every information on the server
until it is null
and your server also reads all the time and is waiting for any input..
so as long as server and client are waiting for input, no one will receive any data.
try to think of a protocol to communicate between the server and the client.
e.g
Sever to Client: Hello Who are you?
Client receives Data and replies: Client
Server receives Information: You Are now authorized, what ya gonna do?
and so on ^^
also out.flush() is needed to send a message

linking my applet to a server dirctory to recieve or save a file from there?

I' m looking for a code to save the files created in a applet normally text files i want to save them on a server directory how can i do so.
Here is an example of how to send a String. In fact any Object can be sent this method so long as it's serializable and the same version of the Object exists on both the applet and the servlet.
To send from the applet
public void sendSomeString(String someString) {
ObjectOutputStream request = null;
try {
URL servletURL = new URL(getCodeBase().getProtocol(),
getCodeBase().getHost(),
getCodeBase().getPort(),
"/servletName");
// open the connection
URLConnection con = servletURL.openConnection();
con.setDoOutput(true);
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "application/octet-stream");
// send the data
request =
new ObjectOutputStream(
new BufferedOutputStream(con.getOutputStream()));
request.writeObject(someString);
request.flush();
// performs the connection
new ObjectInputStream(new BufferedInputStream(con.getInputStream()));
} catch (Exception e) {
System.err.println("" + e);
} finally {
if (request != null) {
try {
request.close();
} catch (Exception e) {
System.err.println("" + e);
};
}
}
}
To retrieve on the server side
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) {
try {
// get the input stream
ObjectInputStream inputStream = new ObjectInputStream(
new BufferedInputStream(request.getInputStream()));
String someString = (String)inputStream.readObject();
ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(response.getOutputStream()));
oos.flush();
// handle someString....
} catch (SocketException e) {
// ignored, occurs when connection is terminated
} catch (IOException e) {
// ignored, occurs when connection is terminated
} catch (Exception e) {
log.error("Exception", e);
}
}
No one is going to hand you this on a plate. You have to write code in your applet to make a socket connection back to your server and send the data. One way to approach this is to push the data via HTTP, and use a library such as commons-httpclient. That requires your server to handle the appropriate HTTP verb.
There are many other options, and the right one will depend on the fine details of the problem you are trying to solve.