Broadcast Message in Java - java

I need some mechanism that allows me to transfer some data from one java program to another within a same PC. I already investigated RMI but I want 1st app to broadcast some message for 2nd without request of 2nd application. In RMI only client can initiate a communication.
Raw sockets are also not desirable (very low level).
I need something like RMI with a different scheme of starting communication: 1 server broadcasts messages for several clients without requests from clients.
Could you please suggest me some libs/technologies (for desktop app)?

I suggest you to use java messaging service and one of it's implementations such as ApacheMQ.
A good starting point is here.

I would suggest using a database with a trigger and store procedure. Here is an example of calling java methods from the database. A message queue will work, but that is an overly complex solution.
Here's an excerpt from an example of how to create a procedure and call it via a trigger:
First, you add the following Java method to the class DBTrigger
CREATE OR REPLACE PROCEDURE add_emp (
emp_no NUMBER, emp_name VARCHAR2, dept_name VARCHAR2)
AS LANGUAGE JAVA
NAME 'DBTrigger.addEmp(int, java.lang.String, java.lang.String)';
Then, you create the INSTEAD OF trigger:
CREATE OR REPLACE TRIGGER emps_trig
INSTEAD OF INSERT ON emps
FOR EACH ROW
CALL add_emp(:new.empno, :new.ename, :new.dname);

Since you tagged this with CORBA, you could use the Event Service to broadcast a notice to all interested clients.

To enable the server to send packets of information to the client/clients. A datagram, by definition, is “an independent, self-contained message sent over the network whose arrival, arrival time, and content are not guaranteed”. Essentially, we are opening a DatagramSocket in order to send DatagramPacket messages to the client. We are using the datagram classes (instead of standard sockets) because they allow us to broadcast information to multiple clients, that are all connected to a MulticastSocket.
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class MulticastSocketServer {
final static String INET_ADDR = "224.0.0.3";
final static int PORT = 8888;
public static void main(String[] args) throws UnknownHostException, InterruptedException {
// Get the address that we are going to connect to.
InetAddress addr = InetAddress.getByName(INET_ADDR);
// Open a new DatagramSocket, which will be used to send the data.
try (DatagramSocket serverSocket = new DatagramSocket()) {
for (int i = 0; i < 100; i++) {
String msg = "Sent message no " + i;
// Create a packet that will contain the data
// (in the form of bytes) and send it.
DatagramPacket msgPacket = new DatagramPacket(msg.getBytes(),
msg.getBytes().length, addr, PORT);
serverSocket.send(msgPacket);
System.out.println("Server sent packet with msg: " + msg);
Thread.sleep(500);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
One thing that we need to take into consideration here, is that there are specific addresses that allow us to use a MulticastSocket are limited, specifically in the range of 224.0.0.0 to 239.255.255.255. Some of them are reserved, like 224.0.0.0. The address that we are using, 224.0.0.3, can be used safely.
Regarding the client, we are going to move a little bit differently. We are going to create a client class, that will accept incoming messages from the server, and then we are going to duplicate this class. The point here is that by using the same code, we can connect to the server seamlessly, while having as many clients as we like.
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
public class MulticastSocketClient
{
final static String INET_ADDR = "224.0.0.3";
final static int PORT = 8888;
public static void main(String[] args) throws UnknownHostException {
// Get the address that we are going to connect to.
InetAddress address = InetAddress.getByName(INET_ADDR);
// Create a buffer of bytes, which will be used to store
// the incoming bytes containing the information from the server.
// Since the message is small here, 256 bytes should be enough.
byte[] buf = new byte[256];
// Create a new Multicast socket (that will allow other sockets/programs
// to join it as well.
try (MulticastSocket clientSocket = new MulticastSocket(PORT)){
//Joint the Multicast group.
clientSocket.joinGroup(address);
while (true) {
// Receive the information and print it.
DatagramPacket msgPacket = new DatagramPacket(buf, buf.length);
clientSocket.receive(msgPacket);
String msg = new String(buf, 0, buf.length);
System.out.println("Socket 1 received msg: " + msg);
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
First, we start the clients, which will keep waiting for incoming packets of information. As soon as we start the server, it will send the information packets and the clients will receive them and print the information on the screen

ZeroMQ could be what you are searching, but I have only used it in C, C++ and Python, so I am not totally sure of how well it is usable in Java. But they have implemented the Publisher-Subscriber pattern for their sockets and at least the static library of the version 3.2.2 under ubuntu 12.04 is stable and works very well.

As a "quick fix" write the output to file and have the second app read the file.
This is not elegant at all, but if you code to interfaces you can later replace the implementation with something better.

A good solution would be an implementation of the OMG Data Distribution Standard (DDS). With DDS there is just a global data space with a dynamic discovery protocol. See for example RTI DDS, there is a free community edition.

Related

How do i get the port and address of client without receiving data from it first?

I'm making a simple UDP chat program, and i would like the server to be able to send to the client without receiving data from it first. Normally, when it receives data from the client, the server gets the IP and port of the client, so it can communicate with it.
My server code:
package com.ageforce;
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class ChatServer {
DatagramSocket server;
byte[] receivedData = new byte[1024];
Scanner scanner = new Scanner(System.in);
byte[] sentData;
DatagramPacket dp2 = new DatagramPacket(receivedData, receivedData.length);
public ChatServer() throws SocketException {
server = new DatagramSocket(7000);
}
public static void main(String[] args) throws SocketException {
ChatServer cs = new ChatServer();
Thread receiveMessage = new Thread(() -> {
while (true) {
try {
cs.server.receive(cs.dp2);
} catch (IOException e) {
e.printStackTrace();
}
String storedData = new String(cs.dp2.getData());
System.out.println(storedData);
}
});
Thread sendMessage = new Thread(() -> {
while (true) {
String sentMessage = cs.scanner.nextLine();
cs.sentData = sentMessage.getBytes();
// This is the area of the code where the server gets IP and port of client from the received data. I'd like this to be changed.
InetAddress getIP = cs.dp2.getAddress();
int port = cs.dp2.getPort();
DatagramPacket dp3 = new DatagramPacket(cs.sentData, cs.sentData.length, getIP, port);
try {
cs.server.send(dp3);
} catch (IOException e) {
e.printStackTrace();
}
}
});
sendMessage.start();
receiveMessage.start();
}
}
Is it possible to do this? Any reply is greatly appreciated.
How do i get the port and address of client without receiving data from it first?
UDP does not afford that possibility. It is a connectionless protocol, so the server doesn't even know that there is a client until it receives a message from it.
You could conceivably create some kind of preliminary application-level protocol whereby the client announces itself to the server before sending it any chat data, but nothing of the sort is part of UDP itself, and if that's something you want then you should consider using TCP instead, which does have a built-in concept of establishing a connection before sending any data.
In order to send an UDP message to something, you need to know the IP and port number to send it to. How? Well, you tell me.
The way your protocol works right now is that the clients know your hostname (which they let their system turn into an IP automatically), and the port number is hardcoded in the client app. The server knows which IP and port to send data back to by checking the 'sender' IP/port when it receives a call.
If you don't like your current protocol you'll need to figure out a different way to answer this question.
Even if you find a way, you'll find that this is mostly useless. The vast majority of end-users intentionally do not have a so-called publically routable IP address. You cannot reach them by design. In your current protocol, that IP/port combo you send back to isn't really the sending computer at all. It's some router, for example the router in their home. That router saw the outgoing UDP packet and is remembering for a while: Any traffic coming in on that port is supposed to go to that computer in this house.
Short of completely crazy stuff such as 'hole punching' (which skype used for a while, not sure if they still do, it's a complicated hack that doesn't always work and is surely not what you want here - you can search the web for that term), there's simply nothing you can do here. end-user systems aren't servers and cannot be reached like this.
Your run-of-the-mill chat apps will always have clients ping the server and then just keep that connection open as long as they can.

Sending objects between Python/Java server/client

I have a Python client and a Java server. I would like the client to send an object to the server. How to implement this?
How to also implement the other way around (Java client - Python server)?
Here's an attempt I made with Python server and Java client:
PYTHON SERVER SIDE
import pickle
import socket
from simple_message import SimpleMessage
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 9999))
s.listen(1)
while True:
print("Waiting for a message...")
conn, addr = s.accept()
data = conn.recv(4096)
incoming_message = pickle.loads(data)
conn.close() # Close connection, not needed anymore
print(SimpleMessage.get_payload(incoming_message))
The object it refers to (of class SimpleMessage) is defined as follows:
#!/usr/bin/env python
class SimpleMessage:
dest_address = str()
message_type = int()
payload = str()
def __init__(self, dest_address, message_type, payload):
self.dest_address = dest_address
self.message_type = message_type
self.payload = payload
def get_payload(self):
return self.payload
JAVA CLIENT SIDE
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
public class JavaClient {
public static void main(String[] args) throws IOException {
Socket sendingSocket = new Socket();
sendingSocket.connect(new InetSocketAddress("127.0.0.1", 9999));
OutputStream outputStream = sendingSocket.getOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
SimpleMessage message = new SimpleMessage("127.0.0.1", 1, "Test message!");
objectOutputStream.writeObject(message); // Write Message on socket
sendingSocket.close();
}
}
And the class SimpleMessage:
import java.io.Serializable;
public class SimpleMessage implements Serializable {
private String destAddress;
private Integer messageType;
private String payload;
public SimpleMessage(String destAddress, Integer messageType, String payload) {
this.destAddress = destAddress;
this.messageType = messageType;
this.payload = payload;
}
}
OUTPUTS
Here is the output I get on the Python server side:
Waiting for a message...
Traceback (most recent call last):
File "python_server.py", line 16, in <module>
incoming_message = pickle.loads(data)
_pickle.UnpicklingError: invalid load key, '\xac'.
And here's the output I get on the Java client side:
Exception in thread "main" java.net.SocketException: Broken pipe (Write failed)
at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1883)
at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1792)
at java.base/java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1287)
at java.base/java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1232)
at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1428)
at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
at java.base/java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1583)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:352)
This is a specific instance of choosing a serialization format.
https://en.wikipedia.org/wiki/Comparison_of_data-serialization_formats
This is a potentially overbroad topic, so I will hold back from a long and possibly redundant answer considering all possible formats.
JSON is a good and currently fashionable format which will get you started, but also potentially work well more involved use cases in the future. There are well-known libraries in Python and Java.
No matter what you choose, if there is any use outside a small prototype or assignment, defining an explicit schema lays a good foundation for future work (eg using JSON schema for JSON).
pickle, as in your original example code, is a Python-specific serialization format. So unless you have some specific use for a tool like Jython in your Java world, it's not a great choice for communicating over a network with a service that can be written in another language.
You should also consider whether low level sockets are the best choice for your use case, or a higher level network library like HTTP may be a better fit.
What you are talking about here is also known as decoupling of elements in the systems.
This gives you a lot of flexibility to change languages and implementation in the system and this is also the method that is used when different backend services talk with each other in a micro-services architecture.
The common way to do it is to select a JSON protocol that the two sides transfer between each other: For example:
{
fName: "David",
lName: "Gold"
}
And then to make HTTP calls to GET or POST data between your two elements.
By doing so, you are free to change the implementation on each side (let's say you discover that you better write your client in JavaScript and the server in R).
As long as both sides keep working with the same protocol, they are agnostic to the implementation that the other side uses.

Simple STUN client in java

I have found several java STUN implementations
Java and Which Stun libraries i should use?
There is
JSTUN: http://jstun.javawi.de/
STUN: http://java.net/projects/stun
See also: STUN, TURN, ICE library for Java
But it is jars with many classes. I wish to find something simple in form of single method or at least single small class. Like following python code.
https://github.com/jtriley/pystun/blob/develop/stun/init.py
Reasonable answer why STUN in Java is so huge is also acceptable.
Reasonable answer why STUN in Java is so huge is also acceptable.
It's a reasonable question. 99% of what STUN is just a simple echo/response protocol for a client to self-discover the IP and port mapping as a result of NAT between it and the public internet. Having built a STUN library in C++, I have some insight.
Let's think about what is required of a STUN library:
A message writer that generates the STUN messages with an attribute field schema that not only allows for fields to appear in any order, it also allows for custom attributes to be added as well.
A message parser that can read such messages back and convert a data
structure reasonable for code to use. It needs to do this securely and avoid unhandled exceptions.
Socket networking code to send/receive such messages. And STUN servers are technically required to listen on 2 IPs and 2 ports, so that makes the networking code for the server a bit more complex.
If we just care about binding requests and binding responses, we'd be
done. But the STUN RFCs also define a set of NAT classification tests. So additional state machine logic is needed to make any such library complete.
And if the STUN library is going to go all the way with the security options afforded by the protocol, it would need some amount of crypto code for hashing and signing of messages
So combining all this into a library that anyone can use for all the different purposes of STUN including mapped address discovery, NAT classification, and ICE negotiation, it starts to get big quick.
You could easily just roll some socket code that hardcodes the bytes of a binding request and then some hacked up parsing to parse the response. That might meet your own needs, but a well established open source library would never be written this way.
JSTUN is a good start. I've shared some interop and bug fixing code with the original author. He doesn't actively maintain it, but it's a good implementation of RFC 3489. I even hacked it up once to run on Android.
To generate a STUN binding request in JSTUN.
MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
sendMH.generateTransactionID();
// add an empty ChangeRequest attribute. Not required by the standard, but JSTUN server requires it
ChangeRequest changeRequest = new ChangeRequest();
sendMH.addMessageAttribute(changeRequest);
byte[] data = sendMH.getBytes();
// not shown - sending the message
Then to parse the response back:
byte [] receivedData = new byte[500];
// not shown - socket code that receives the messages into receivedData
receiveMH.parseAttributes(receivedData);
MappedAddress ma = (MappedAddress) receiveMH.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);
Then combine the above with some socket code. The best example of combining the above with socket code can be found in the DiscoveryTest.java source file. You really just need the code in the test1() method of this class.
MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
// sendMH.generateTransactionID();
// add an empty ChangeRequest attribute. Not required by the
// standard,
// but JSTUN server requires it
ChangeRequest changeRequest = new ChangeRequest();
sendMH.addMessageAttribute(changeRequest);
byte[] data = sendMH.getBytes();
s = new DatagramSocket();
s.setReuseAddress(true);
DatagramPacket p = new DatagramPacket(data, data.length, InetAddress.getByName("stun.l.google.com"), 19302);
s.send(p);
DatagramPacket rp;
rp = new DatagramPacket(new byte[32], 32);
s.receive(rp);
MessageHeader receiveMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingResponse);
// System.out.println(receiveMH.getTransactionID().toString() + "Size:"
// + receiveMH.getTransactionID().length);
receiveMH.parseAttributes(rp.getData());
MappedAddress ma = (MappedAddress) receiveMH
.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);
System.out.println(ma.getAddress()+" "+ma.getPort());
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import de.javawi.jstun.attribute.ChangeRequest;
import de.javawi.jstun.attribute.ChangedAddress;
import de.javawi.jstun.attribute.ErrorCode;
import de.javawi.jstun.attribute.MappedAddress;
import de.javawi.jstun.attribute.MessageAttribute;
import de.javawi.jstun.attribute.MessageAttributeException;
import de.javawi.jstun.attribute.MessageAttributeParsingException;
import de.javawi.jstun.header.MessageHeader;
import de.javawi.jstun.header.MessageHeaderParsingException;
import de.javawi.jstun.util.UtilityException;
public class StunTest { public static void main(String[] args) throws UtilityException, IOException {
MessageHeader sendMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
// sendMH.generateTransactionID();
// add an empty ChangeRequest attribute. Not required by the
// standard,
// but JSTUN server requires it
ChangeRequest changeRequest = new ChangeRequest();
sendMH.addMessageAttribute(changeRequest);
byte[] data = sendMH.getBytes();
DatagramSocket s = new DatagramSocket();
s.setReuseAddress(true);
DatagramPacket p = new DatagramPacket(data, data.length, InetAddress.getByName("stun.l.google.com"), 19302);
s.send(p);
DatagramPacket rp;
rp = new DatagramPacket(new byte[32], 32);
s.receive(rp);
MessageHeader receiveMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingResponse);
// System.out.println(receiveMH.getTransactionID().toString() + "Size:"
// + receiveMH.getTransactionID().length);
try {
receiveMH.parseAttributes(rp.getData());
} catch (MessageAttributeParsingException e) {
e.printStackTrace();
}
MappedAddress ma = (MappedAddress) receiveMH
.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);
System.out.println(ma.getAddress()+" "+ma.getPort());
}
}

Java UDP STUN Hole Punching with DatagramSocket

I'm trying to to send a udp packet to a client across a NAT, both of us belong to a different NAT, we are familiar with the theory of STUN therefore the way to achieve this is to 'hole punch' our way through via a simple STUN server..
Basically the server just returns external IP address and port of another client that is 'connected' which I can then use it to send the packet to the client across the NAT... however though we managed to get each other's external ip and ports..we are still unable to receive anything from each other after sending... After searching through forums and many hours of head scratching we are still unable to come up with a solution...was wondering if anyone who is familiar with STUN to able to give us some pointers or advice on where we've gone wrong...
Below is our small client we've written...
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import javax.swing.JOptionPane;
public class Client {
DatagramSocket socket;
public Client(){
try {
socket = new DatagramSocket();
String data = "Initiate Stun Server";
byte[] receive = data.getBytes();
InetAddress host = InetAddress.getByName("the.stun.server.ipaddress");
DatagramPacket pk = new DatagramPacket(receive,receive.length,host,9345);
socket.send(pk); //send packet to server to initiate udp communication
//spawn a new Thread to listen for any incoming packets
new Thread(){
public void run(){
byte[] r;
DatagramPacket rp;
while(true){
System.out.println("Start listening on new socket");
r = new byte[1024];
rp = new DatagramPacket(r,r.length);
try {
socket.receive(rp);
System.out.println(new String(rp.getData()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
String m = JOptionPane.showInputDialog(null,"Enter message to send");
InetAddress connect = InetAddress.getByName(JOptionPane.showInputDialog(null,"Enter address to send message to"));//This is where we input the external ip
int connectPort = Integer.parseInt(JOptionPane.showInputDialog(null,"Enter port of the addressee"));//input port
DatagramPacket p = new DatagramPacket(m.getBytes(),m.getBytes().length,connect,connectPort);
socket.send(p);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]){
Client c = new Client();
}
}
What you implemented is not the true STUN protocol, but will likely suffice. :)
But I think I see two problems in your code.
You aren't saving the local port number. After you get the response back from the stun server, you need to call socket.getLocalPort to find out what your internal port number that corresponds to the "mapped port". The mapped port is the port that your stun server sees you at. Your NAT will continue to map outbound traffic from your PC's IP, to that mapped port, but only if you use the same local port. So in your subsequent connection to your peer, create the datagram socket on that same port (after closing the original socket), or just reuse the same socket for a subsequent communication to a peer, as the socket is already binded.
Just because you know the remote host's external IP address and his port mapping for his local socket, doesn't mean his NAT is going to forward your packets. Most NATs run as "IP and port restricted". This means that it will only allow inbound traffic, including UDP packets, through the NAT if it knows that there was a corresponding outbound UDP packet for the same remote host's IP and port. If it didn't have this rule in place, it wouldn't know which PC behind the NAT to forward the packet to. Typical NAT traversal technique is for both peers to send simple 1-byte datagrams to each other at the same time, and to try repeatedly (more than once). The first packet tries to leave the host and out of its own NAT, but will likely get blocked by the remote NAT (because it doesn't know who you are). But it does cause your NAT to create a mapping and forwarding entry for the other side to successfully send to you. Eventually, both NATs will allow and forward traffic between both peers.
There are also types of NATs with unpredictable port mapping behavior. (Port mapping changes on a per-IP basis). These are difficult to traverse (with with STUN), but usually works out ok if the other side has a well behaved NAT. Fortunately, these types of NATs are rarer than they used to be.
Here's some links:
ICE (standard mechanism on P2P via usage of STUN and TURN): http://en.wikipedia.org/wiki/Interactive_Connectivity_Establishment
My P2P connectivity in a nutshell answer I gave a while back.
Also, a blatant plug to use my STUN server code base. You can use it in conjunction with the JStun client library.

How can I modify this code to allow my client socket program to send a string to the server?

Hi ive written some code to connect to a server through the use of a socket. Id like to write some simple code that allows me to send a string to the server, im assuming this will involve input and output streams but I am new to this. Ive put the code I am working with below, any insights into the best way to accomplish this would be great.
import java.net.*;
import java.io.*;
public class SocketMarket
{
public static void main(String [] args)
{
String serverName = "XX.X.X.XXX";
int port = XXXX;
try
{
System.out.println("Connecting to " + serverName + " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Connected to " + client.getRemoteSocketAddress());
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
Thanks in advance
client.getOutputStream().write("Hello World".getBytes());
client.getOutputStream().flush();
The above is how you would send just a String, but you will probably want to build up some infrastructure around sending arbitrary text.
The general idea is that your server and client will communicate with each other using InputStream's and OutputStream's, which can be accessed from a Socket via getInputStream() and getOutputStream(), once the connection between them is made.
For your server to receive connections, you should be using a ServerSocket to accept() incoming connections.
Insight is here, the "really big index" for java.
http://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
Yes, it involves OutputStreams. If you want to output Strings you could write raw bytes via the OutputStream you get from the connection but then you completely loose control over encoding. You need to learn about reader/writer/streams first, then networking via sockets is simple. You can find the relevant part of the Java tutorials here: http://docs.oracle.com/javase/tutorial/essential/io/ (you can ignore the NIO part completely for the beginning). After that you can learn about socket networking: http://docs.oracle.com/javase/tutorial/networking/sockets/index.html .

Categories