How to receive object in java socket programming? - java

I'm new in java network programming.
I wrote a simple client-server code that sends object of a class from client to server.
I used PrintStream to send object and it's ok, but cannot receive it at the server when using BufferedReader
Client Code:
public class Client3 {
public String username;
public String password;
public static void main(String argv[]) throws IOException
{
Client3 account = new Client3();
account.username = "PJA";
account.password = "123456";
Socket s = new Socket("localhost",6000);
PrintStream pr = new PrintStream(s.getOutputStream());
pr.println(account);
}
}
Server Code:
public class Server3 {
public static void main(String argv[]) throws IOException
{
ServerSocket s1 = new ServerSocket(6000);
Socket s = s1.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
Client3 a = new Client3();
a = in.readLine(); // give a compilation error.
}
}
readline() throws a compilation error because it takes only a string.
so my question is: "Is there a way to receive object of a class?"

Q: "Is there a way to receive object of a class?"
A: Yes, there are many MANY ways:
Java RMI
Java SOAP Web services
You can use native Java serialization and write directly to a Java socket (basically, re-invent your own RMI): http://www.coderpanda.com/java-socket-programming-transferring-of-java-objects-through-sockets/, or http://www.jguru.com/faq/view.jsp?EID=10472. If you mark your objects "serializable", then you can simply useoutputStream.writeObject() to write and ObjectInputStream() to read.
You read and write your object state into JSON and send JSON text over your socket: http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
Etc. etc.
Option 3) is closest to what you're asking about. I'd also encourage you to consider Option 4). Here's a good tutorial: http://tutorials.jenkov.com/java-json/jackson-objectmapper.html

Related

Add variable to Java OPCUA server

I would like to use a java OPC UA server with the prosys OPCUA SDK.
I'm able to start a server with the SimpleServer program but I don't understand how to host variable in this server as boolean, integer...
Here the code I'm using from the package, it start a server but it is empty.
public class SimpleServer {
public static void main(String[] args) throws Exception {
UaServer server = new UaServer();
if (System.getProperty("java.version").startsWith("1.6")) {
server.setEnableIPv6(false);
}
server.setPort(Protocol.OpcTcp, 52530);
server.setServerName("OPCUA/SimpleServer");
server.setBindAddresses(EndpointUtil.getInetAddresses(server.isEnableIPv6()));
server.getSecurityModes().add(SecurityMode.NONE);
server.getSecurityModes().addAll(SecurityMode.combinations(
EnumSet.of(MessageSecurityMode.Sign, MessageSecurityMode.SignAndEncrypt), SecurityPolicy.ALL_SECURE_104));
server.addUserTokenPolicy(UserTokenPolicies.ANONYMOUS);
server.setCertificateValidator(new DefaultCertificateValidator(new PkiDirectoryCertificateStore()));
initializeApplicationIdentity(server);
// Starts the server
server.start();
// Prints connection address that clients can use.
System.out.println("Server started, connection address:");
System.out.println(server.getEndpoints()[0].getEndpointUrl());
//I think the variable should be add here
// Wait for shutdown
System.out.println("Enter 'x' to shutdown");
Scanner sc = new Scanner(System.in);
sc.nextLine(); // blocks until input given
System.out.println("Shutting down..");
server.shutdown(2, new LocalizedText("Shutdown by user"));
System.out.println("Server stopped.");
}
/**
* Define a minimal ApplicationIdentity.
*/
private static void initializeApplicationIdentity(UaServer server)
throws SecureIdentityException, IOException, UnknownHostException {
ApplicationDescription appDescription = new ApplicationDescription();
appDescription.setApplicationName(new LocalizedText("SimpleServer", Locale.ENGLISH));
appDescription.setApplicationUri("urn:localhost:UA:SimpleServer");
appDescription.setProductUri("urn:prosysopc.com:UA:SimpleServer");
appDescription.setApplicationType(ApplicationType.Server);
File privateKeyPath = new File("PKI/CA/private");
String organization = "Sample Organization";
String privateKeyPassword = "opcua";
ApplicationIdentity identity = ApplicationIdentity.loadOrCreateCertificate(appDescription, organization,
privateKeyPassword, privateKeyPath, true);
server.setApplicationIdentity(identity);
}
} ```
Please, take a look at the SampleConsoleServer project which is a more complete server. And read the Tutorial that explains the details.

Running into an java.net.BindException: Address already in use (Bind failed) on server- client socket app [duplicate]

I am Running into a java.net.BindException: Address already in use (Bind failed) on a server-client socket app
I am trying to learn about Java sockets using a Youtube tutorial as a reference. My code seems to match everything in the video (except variables names) but, when trying to run the server and then the client sockets, I get:
Exception in thread "main" java.net.BindException: Address already in use (Bind failed)
I have tried even printing out the local port just to make sure I connect to the right available port but, nothing works. Is there any documentation I can look into to solve this problem? or any guidance?
Server.java
public class serverSocket {
public static void main(String args[]) throws IOException{
String message, serverResponse;
ServerSocket serverSocket = new ServerSocket(56789);
System.out.print(serverSocket.getLocalPort());
Socket acceptClientRequestSocket = serverSocket.accept();
Scanner serverScanner = new Scanner(acceptClientRequestSocket.getInputStream());
message = serverScanner.next();
System.out.println(message);
serverResponse = message.toUpperCase();
PrintStream newMessage = new PrintStream(acceptClientRequestSocket.getOutputStream());
newMessage.println(serverResponse);
}
}
Client.java
public class clientSocket {
public static void main(String args[]) throws UnknownHostException, IOException {
String message,outputMessage;
Scanner clientInput = new Scanner(System.in);
Socket clientSocket = new Socket("localhost",56789);
Scanner incomingStream = new Scanner(clientSocket.getInputStream());
System.out.println("Enter a message");
message = clientInput.next();
PrintStream printClientStream= new PrintStream(clientSocket.getOutputStream());
printClientStream.println(message);
outputMessage = incomingStream.next();
System.out.println(outputMessage);
}
}
Is there any documentation I can look into to solve this problem? or any guidance?
You have probably your previously exectued program still running. Check the running java processes. Kill the the previous one and try again.
If this wouldn't help try restarting your machine. If the problem persists after that then some service is already running on this port and is starting with the OS. In that case you can either change the port number in your app or disable that service.

Calling Matlab by JADE agent as multi-threading for multiple connections

I am working on JADE (Java) project that connects Matlab by a TCP connection with client-server sockets. Here, JADE creates a server socket and Matlab creates a client socket. I am retrieving some data from Matlab to Java (JADE). The following is my code where I am calling Matlab by JADE through Agent. (1) The issue is I cannot re-run it without re-starting the program again. I believe that I require a multithread java instance with multithread Matlab instance that could connect and synchronize each other. However, I found that Matlab is a single thread. The program throws binding error.
WARNING: Error adding ICP jade.imtp.leap.JICP.JICPPeer#1dbb27d[Cannot bind server socket to localhost port 1099].
jade.core.AgentContainerImpl joinPlatform
SEVERE: Communication failure while joining agent platform: No ICP active
jade.core.IMTPException: No ICP active
I want to run it multiple times without manually re-starting. Here is my JADE code (took help from https://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html):
public class MatlabComAgent extends Agent
{
ServerSocket srvr = null;
Socket skt = null;
BufferedReader in;
PrintWriter out;
String ip = "localhost";
String filePath;
int port = 1234;
protected void setup()
{
// Get arguments
Object[] args = getArguments();
filePath = (String) args[0];
// Create the TCP connection
try
{
// Create server and socket
srvr = new ServerSocket(port);
skt = srvr.accept();
// Create writer and reader to send and receive data
out = new PrintWriter(skt.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
}
catch (IOException e)
{
e.printStackTrace();
}
// Send a message to the tester to say its can start sending requests
sendMessage("Tester","","start-now",ACLMessage.INFORM);
// Run behavior
CommWithMatlab commWithMatlab = new CommWithMatlab();
addBehaviour(commWithMatlab);
} // End setup
Code for Matlab connection:
% Create TCP/IP object 't'. Specify server machine and port number.
% Open the connection with the server
t = tcpip('localhost', 1234);
set(t, 'InputBufferSize', 30000);
set(t, 'OutputBufferSize', 30000);
pause(0.1)
fopen(t);
disp('Connection with JADE established')
I found interesting notes on "socket server which allows multiple connections via threads and Java" Creating a socket server which allows multiple connections via threads and Java page, however, I am not able to do it completely what is said here. May be I am missing something here. (2) I am confused should I edit my Matlab code and/or JADE code for multi-threading.
Here is my code that I tried:
protected void setup()
{
// Get arguments
Object[] args = getArguments();
filePath = (String) args[0];
// Create the TCP connection
try
{
srvr = new ServerSocket(port);
Runnable connectionHandler = new ConnectionHandler(skt);
new Thread(connectionHandler).start();
}
catch (IOException e)
{
e.printStackTrace();
}
Here is new ConnectionHandler class:
public class ConnectionHandler implements Runnable {
private Socket sk=null; //initialize in const'r
BufferedReader in;
PrintWriter out;
public ConnectionHandler(ServerSocket skt) throws IOException
{
sk = skt.accept();
out = new PrintWriter(sk.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sk.getInputStream()));
}
public void run() {
try
{
// Create writer and reader to send and receive data
out = new PrintWriter(sk.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(sk.getInputStream()));
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
But I got some erorr "java.lang.NullPointerException". Can someone help me to properly code it, what I am missing. Also, (3) this run() in ConnectionHandler class will be invoked automatically? I was confused so I create writer and reader inside Connectionhandler class and its run(). Can I simply make my MatlabComAgent class as multithread without adding any new class. I can make my class as
public class MatlabComAgent extends Agent implements Runnable
{....
....
}
Should I also put the following inside ConnectionHandler class?
// Send a message to the tester to say its can start sending requests
sendMessage("Tester","","start-now",ACLMessage.INFORM);
// Run behavior
CommWithMatlab commWithMatlab = new CommWithMatlab();
addBehaviour(commWithMatlab);
Here, CommWithMatlab class extends SimpleBehavior containg required actions that further passes commands from Matlab to PowerWorld (using another connection). One example is like:
class CommWithMatlab extends SimpleBehaviour
{
private static final long serialVersionUID = 8966535884137111965L;
#Override
public void action()
{
// Wait for a message from another agent requesting something
ACLMessage msg = blockingReceive();
// If this is to open a case
if(msg.getConversationId().equals(OPEN_CASE))
{
openCase(msg.getContent());
}
}
I can simple pass arguments to addagent() and can call runJade(). The following are my JADE run functions using agents:
//Runs JADE and starts the initial agents
public static void runJade() throws ControllerException
{
// Launch JADE platform
Runtime rt = Runtime.instance();
Profile p;
p = new ProfileImpl();
cController = rt.createMainContainer(p);
rt.setCloseVM(true);
// Launch Powerworld interface agent
addAgent(PWRWORLD_NAME, PWRWORLD_CLASS, null);
addAgent(PWRWORLD_TESTER_NAME, PWRWORLD_TESTER_CLASS, null);
//addAgent(PWRWORLD_TESTER_NAME2, PWRWORLD_TESTER_CLASS2, null);
}
private static void addAgent(String name, String type, String arg) throws ControllerException
{
Object[] argsObj = {arg};
AgentController ac = cController.createNewAgent(name, type, argsObj);
ac.start();
}
(4) I have a different program that also creates the same connection. When I try to run one program when other is running, it again throws binding error. However, these programs are completely separate. One program uses port 1234 and other 1239. However, system always assign local port to 1099 to both programs, hence throw binding error in this case.
Any help is appreciable!
Unfortunately, it is not possible to use matlabcontrol over a distributed network. I checked.

What should a Socket Thread class do [duplicate]

This question already has an answer here:
Java Multiple threads for just 2 computers, how to do it in main
(1 answer)
Closed 7 years ago.
public class SOCKET_SERVER {
private JmailHelp JmailHELPER = new JmailHelp();
static int PORT = 444;
public static void main(String[] args) throws Exception {
SOCKET_SERVER SERVER = new SOCKET_SERVER();
SERVER.JmailHELPER.resetONN();
ServerSocket SRVSOCK = new ServerSocket(PORT);
//ArrayList<SocketStatus> OnlineUsers = new ArrayList<SocketStatus>();
Socket SOCK = SRVSOCK.accept();
//new ServerThread(SOCK).start();
SocketStatus a = new SocketStatus(SOCK, false);
//OnlineUsers.add(a);
//String action = "";
SERVER.ServerActionsHandler(SERVER, SRVSOCK, SOCK, a);
}//
}
forgive me if what i am giving is not enough don't hesitate to ask more if you can and want to try to help me
Well,
this is my socket server class ServerActionHandler is a method i created that takes as "input"(by BufferedReader) from the client a string and calls the right methods to serve the client.
for example he wants to login:
he(client) sends the string "login"
then server takes it as an "input" by the ServerActionHandler in a string called action, then recognise the the "login" and then calls the Acceptlogin method from the server class
Meanwhile client who send the "logi message" is calling the Dologin method from the client class
4.a loop of the ServerActionsHandler ends
5.A new loop starts asking the new action from the Client
my project works for A server and One client
I want to make it working for many clients
also something more I use JmailHELPER object
in almost all the methods of SOCKET_SERVER class(eg. login_accept,register_accept...)
in order to call some methods of it's class.
And SocketStatus keeps one variable if the certain socket which uses the Server is logged in or not
from what I know i have to make a ServerThreads class that extends Threads to handle more than one users.
What is the constructor and the run of that classmethod supposed to do
for example of A SocketThread I have this http://www.cdk5.net/ipc/programCode/TCPServer.java
thanks.
ok,
I know its funny but after a break of two hours I tried to find the solution for 3 minutes and i solved it(thats what i believe for now :P )
At least it is working on my pc for two clients so I will check it tommorow in more than one pc
Anyway I am posting the answer to my problem so that you can see it if you have a common problem
public static void main(String[] args) throws Exception {
SOCKET_SERVER SERVER = new SOCKET_SERVER();
SERVER.JmailHELPER.resetONN();
ServerSocket SRVSOCK = new ServerSocket(PORT);
while (true) {
Socket SOCK = SRVSOCK.accept();
SocketStatus a = new SocketStatus(SOCK, false);
new Thread() {
public void run() {
try {
SERVER.ServerActionsHandler(SERVER, SRVSOCK, SOCK, a);
} catch (Exception ex) {
Logger.getLogger(SOCKET_SERVER.class.getName()).log(Level.SEVERE, null, ex);
};
}
}.start();
}
}

Problems creating an RTP stream with JMF

I'm at the very early stages of a project requiring the broadcasting, using RTP, of a DataStream created from a MediaLocation. I'm following some example code which currently failingin on the rptManager.initalize(localAddress) with the error "Can't open local data port: xxxx", specifically:
Exception in thread "main" javax.media.rtp.InvalidSessionAddressException: Can't open local data port: 34586
at com.sun.media.rtp.RTPSessionMgr.initialize(RTPSessionMgr.java:2688)
at com.sun.media.rtp.RTPSessionMgr.initialize(RTPSessionMgr.java:2515)
at RTPBroadcast.main(RTPBroadcast.java:20)
I'm developing on Lucid and my firewall is completely disabled. I'm a little stumped to be honest. My code is as follows:
// http://jcs.mobile-utopia.com/jcs/26201_RTPManager.java
public class RTPBroadcast {
public static void main (String[] args) throws InvalidSessionAddressException, IOException, UnsupportedFormatException {
RTPManager rtpManager = RTPManager.newInstance();
SessionAddress localAddress = new SessionAddress();
rtpManager.initialize(localAddress);
InetAddress ipAddress = InetAddress.getByName("192.168.1.5");
SessionAddress remoteAddress = new SessionAddress(ipAddress, 3000);
rtpManager.addTarget(remoteAddress);
DataSource dataOutput = new ScreenSource();
SendStream sendStream = rtpManager.createSendStream( dataOutput, 1);
sendStream.start();
}
}
Any ideas on what could be causing the problem?
If your problem currently isn't solved, try to look at jlibrtp instead of jmf.

Categories