Simple Client-Server Program with NIO channels - java

SOLVED
If anyone would be interested I could edit this post with correct data. Just leave a comment.
As my assignment I had to create a simple server and a client using non-blocking channels and selectors.
Basically it should either echo the message written by the client or add two numbers(also provided by the client).
My problem is that I get errors at point where the message is about to be echoed by server.
I have checked if msg gets to writeResponse method, and it does. So that's where the problem starts.
Thank you all in advance !
Errors I get:
java.io.IOException: An existing connection was forcibly closed by the remote host
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:218)
at sun.nio.ch.IOUtil.read(IOUtil.java:191)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:359)
at SimpleServer.serviceRequest(SimpleServer.java:89)
at SimpleServer.serviceConnections(SimpleServer.java:61)
at SimpleServer.<init>(SimpleServer.java:35)
at SimpleServer.main(SimpleServer.java:141)
Server:
public class SimpleServer {
private ServerSocketChannel ssc = null; //for multiplexing
private Selector selector = null; //monitors channels
private static Charset charset = Charset.defaultCharset();//encoding
private static final int BSIZE = 1024;//buffer size
private ByteBuffer bbuf = ByteBuffer.allocate(BSIZE);
private StringBuffer reqString = new StringBuffer();
public SimpleServer(String host, int port) {
try {
ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ssc.socket().bind(new InetSocketAddress(host, port));
selector = Selector.open(); //selector initiation
ssc.register(selector, SelectionKey.OP_ACCEPT); //registering communication channel
} catch(Exception exc) {
exc.printStackTrace();
System.out.println(1);
}
System.out.println("Server started and is ready for requests");
serviceConnections();
}//constructor
private void serviceConnections() {
boolean serverIsRunning = true;
while(serverIsRunning) {
try {
selector.select();//waits for answer from selector
Set<SelectionKey> keys = selector.selectedKeys(); //set of keys
Iterator<SelectionKey> iter = keys.iterator(); //iterration throught set of keys
while(iter.hasNext()) {
SelectionKey key = (SelectionKey) iter.next(); //obtain key
iter.remove(); //remove, because we'd get it again
if(key.isAcceptable()) {
SocketChannel cc = ssc.accept();//obtaining channel for communication
cc.configureBlocking(false);
cc.register(selector, SelectionKey.OP_READ); //registering selector for monitoring
continue;
}
if(key.isReadable()) { //channel with readable data
SocketChannel cc = (SocketChannel) key.channel();
serviceRequest(cc);
continue;
}
}//while loop
} catch(Exception exc) {
exc.printStackTrace();
continue;
}
}//outer while loop
}//serviceCconnection method
private void serviceRequest(SocketChannel sc) {
if(!sc.isOpen()) return;
reqString.setLength(0);
bbuf.clear();
try {
readLoop:
while (true) {
int n = sc.read(bbuf);
if(n > 0) {
bbuf.flip();//set limit, return to beginning
CharBuffer cbuf = charset.decode(bbuf);
while(cbuf.hasRemaining()) {
char c = cbuf.get();
if (c == '\r' || c == '\n') break readLoop;
reqString.append(c);
}
}
}//while loop
String[] req = reqString.toString().split(" ");
String cmd = req[0];
if (cmd.equals("bye")) {
sc.close();
sc.socket().close();
}
else if(cmd.equals("echo"))
writeResp(sc, reqString.toString());
else if(cmd.equals("add"))
writeResp(sc, Integer.parseInt(req[1]),Integer.parseInt( req[2]));
} catch (Exception exc) {
exc.printStackTrace();
try { sc.close();
sc.socket().close();
} catch (Exception e) {}
}
}//serviceRequest
//overloaded methods
public void writeResp(SocketChannel sc, String msg) throws IOException {
System.out.println(msg);
ByteBuffer cbuf = charset.encode(CharBuffer.wrap(msg));
cbuf = ByteBuffer.allocate(1024);
cbuf.put(msg.getBytes());
cbuf.rewind();
sc.write(cbuf);
}//writeResp method
public void writeResp(SocketChannel sc, int i, int j) throws IOException, NumberFormatException {
int ans = i + j;
String resp = Integer.toString(ans);
ByteBuffer cbuf = charset.encode(CharBuffer.wrap(resp));
sc.write(cbuf);
}//write Resp method
public static void main(String[] args) {
try {
String host = "localhost";
int port = 9998;
new SimpleServer(host, port);
} catch(Exception exc) {
exc.printStackTrace();
System.out.println(1);
}
}//main
}//class
My client:
public class SimpleClient {
private SocketChannel sc;
private static Charset charset;
private StringBuffer reqString = new StringBuffer();
private ByteBuffer bb;
String msg;
public SimpleClient(String host, int port) throws IOException, InterruptedException {
try {
sc = SocketChannel.open();
sc.configureBlocking(false);
sc.connect(new InetSocketAddress(host, port));
System.out.println("Connecting to the server...");
while(!sc.finishConnect()) {
System.out.println("Connection is being established...");
}
} catch (IOException exc) {
System.out.println("IO exception");
System.exit(1);
}
System.out.println("Connection Established!");
makeRequest("echo Test input stream\n");
Thread.sleep(500);
readRequest();
}//constructor
private void makeRequest(String req) throws IOException {
System.out.println("Request: " + req);
bb = ByteBuffer.allocate(1024);
bb.put(req.getBytes());
bb.rewind();
sc.write(bb);
}//makeRequest method
public void readRequest() throws IOException, InterruptedException {
reqString.setLength(0);
bb.clear();
try {
readLoop:
while (true) {
bb.clear();
int readBytes = sc.read(bb);
if(readBytes == 0){
System.out.println("waiting for data");
continue;
}
else if(readBytes == -1) {
System.out.println("Server not responding");
break;
}
else {
bb.flip();
CharBuffer cbuf = charset.decode(bb);
while(cbuf.hasRemaining()) {
char c = cbuf.get();
if (c == '\r' || c == '\n') break readLoop;
reqString.append(c);
}
}
}//while loop
System.out.println(reqString.toString());
} catch( Exception exc) {//while loop
exc.printStackTrace();
}
}//readRequest method
public static void main(String[] args) {
try {
new SimpleClient("localhost", 9998);
}catch (IOException exc) {
exc.printStackTrace();
}catch(InterruptedException exc) {
exc.printStackTrace();
}
}//main method
}//class

If read() returns -1 it doesn't mean 'server not responding'. It means the peer has closed the connection, and you should do likewise. Instead you aren't closing it at all, so the operating system does a reset, so your server gets this exception.

Related

Client doesn't connect to server

I have some server and client code that use nio in java. When I try connected to the server sctpChannel.connect(new InetSocketAddress("127.0.0.1",4545)); returns false. And selector.select() returns 0 . I can't figure out why it happens.
public class SctpNioServer {
public static void main(String[] args)throws Exception{
InetSocketAddress inetSocketAddress = new InetSocketAddress("localhost",4545);
SctpServerChannel serverChannel = SctpServerChannel.open();
serverChannel.bind(inetSocketAddress);
serverChannel.configureBlocking(false);
Selector selector = Selector.open();
serverChannel.register(selector,SelectionKey.OP_ACCEPT );
while(true){
try{
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys() ;
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()){
SelectionKey key = iterator.next();
iterator.remove();
if(key.isAcceptable()){
SctpChannel channel = serverChannel.accept();
channel.configureBlocking(false) ;
channel.register(selector,SelectionKey.OP_READ);
}
if (key.isReadable()){
SctpChannel channel = (SctpChannel) key.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
channel.receive(byteBuffer,null,null);
byteBuffer.flip();
while (byteBuffer.hasRemaining()){
System.out.println((char)byteBuffer.get());
}
byteBuffer.clear();
channel.register(selector, SelectionKey.OP_WRITE);
}
if(key.isWritable()){
//doSomething
}
}
selector.wakeup();
}
catch (IOException e){
e.printStackTrace();
}
finally {
serverChannel.close();
}
}
}}
public class SctpNioClient {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
SctpChannel channel = SctpChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress("localhost", 4545));
Selector sel = Selector.open();
channel.register(sel, SelectionKey.OP_CONNECT);
while (true) {
if (sel.isOpen()) {
int keys = sel.select(5);
if (keys > 0) {
Set<SelectionKey> selectedKeys = sel.selectedKeys();
for (SelectionKey sk : selectedKeys) {
if (!sk.isValid()) {
break;
}
if (sk.isConnectable()) {
channel.finishConnect();
channel.register(sel, SelectionKey.OP_WRITE, channel);
}
if (sk.isWritable()) {
SctpChannel ch = (SctpChannel) sk.channel();
System.out.println("writing->");
ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
String text = scanner.nextLine();
byteBuffer.clear();
byteBuffer.put(text.getBytes());
byteBuffer.flip();
MessageInfo messageInfo = MessageInfo.createOutgoing(null,null,0);
ch.send(byteBuffer,messageInfo);
ch.register(sel , SelectionKey.OP_READ);
sel.wakeup();
}
if(sk.isReadable()){
SctpChannel ch = (SctpChannel) sk.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
ch.receive(byteBuffer,null,null);
byteBuffer.flip();
while (byteBuffer.hasRemaining()){
System.out.println((char)byteBuffer.get());
}
ch.register(sel,SelectionKey.OP_WRITE);
} } } } }
} catch (IOException ex) { }
}}
connect() returns a boolean. You claim that it is false, but your code ignores it.
If it returns true, you don't need to register for OP_CONNECT: but as you are ignoring it you are also ignoring this fact.
finishConnect() also returns a boolean, which you are also ignoring.
All these operations can throw IOExceptions, which you are also ignoring.
Solution: don't. In all cases.

Send multiple files using Java NIO SocketChannel

I have tried sending files using java NIO socket channels according to this guide. It works fine. I modified the method to send List of files. Basically, i loop through the files list and call send method already implemented in the above-mentioned guide. There was an error "Address already in use" so I commented the socket closing line in FileSender class. After that, there was no error in the code. Seems the program stuck in middle. How do I solve this problem? is there any better way to solve the problem?
Main.Java
public static void main(String[] args) throws IOException, InterruptedException{
RunningConfiguration.run();
List<File> files = new <File>ArrayList();
File a = new File("pics/city.jpg");
File b = new File("pics/desert.jpg");
File c = new File("pics/flower.jpg");
File d = new File("pics/night.jpg");
List<Node> nodes = RunningConfiguration.getNodeList();
ListIterator li = nodes.listIterator();
while(li.hasNext()){
Node node = (Node)li.next();
FileSender.send(node, files, "pics/received/");
}
}
FileSender.Java
public class FileSender {
private final InetSocketAddress fileSocketAddress;
private final File file;
public FileSender(InetAddress inetAddress, File file) throws IOException{
this.fileSocketAddress = new InetSocketAddress(inetAddress,RunningConfiguration.FILE_PORT);
this.file = file;
}
public static void send(InetSocketAddress inetSocketAddress, File file) throws IOException{
FileSender nioClient = new FileSender(inetSocketAddress.getAddress(),file);
SocketChannel socketChannel = nioClient.createChannel();
nioClient.sendFile(socketChannel);
}
public static void send(Node to, File file) throws IOException{
FileSender nioClient = new FileSender(to.getSocketAddress().getAddress(),file);
SocketChannel socketChannel = nioClient.createChannel();
nioClient.sendFile(socketChannel);
}
public static void send(Node to, File file,String filepath) throws IOException{
FileSender nioClient = new FileSender(to.getSocketAddress().getAddress(),file);
SocketChannel socketChannel = nioClient.createChannel();
nioClient.sendFile(socketChannel);
}
public static void send(Node to,List<File> files,String filepath) throws IOException{
ListIterator ltr = files.listIterator();
while(ltr.hasNext()){
File file = (File) ltr.next();
FileSender nioClient = new FileSender(to.getSocketAddress().getAddress(),file);
SocketChannel socketChannel = nioClient.createChannel();
nioClient.sendFile(socketChannel);
}
}
public SocketChannel createChannel() {
SocketChannel socketChannel = null;
try {
socketChannel = SocketChannel.open();
SocketAddress socketAddress = this.fileSocketAddress;
socketChannel.connect(socketAddress);
System.out.println("Connected..Now sending the file");
} catch (IOException e) {
e.printStackTrace();
}
return socketChannel;
}
public void sendFile(SocketChannel socketChannel) {
RandomAccessFile aFile = null;
try {
//File file = new File("data\\web.exe");
aFile = new RandomAccessFile(this.file, "r");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (inChannel.read(buffer) > 0) {
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
Thread.sleep(400);
System.out.println("End of file reached..");
socketChannel.close();
aFile.close();
} catch (FileNotFoundException e ) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
FileReceiver.java
private String fileName;
public FileReceiver(String fileName) {
this.fileName = fileName;
}
public static void receive(String fileName) {
FileReceiver nioServer = new FileReceiver(fileName);
SocketChannel socketChannel = nioServer.createServerSocketChannel();
nioServer.readFileFromSocket(socketChannel);
}
public FileReceiver() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public SocketChannel createServerSocketChannel() {
ServerSocketChannel serverSocketChannel = null;
SocketChannel socketChannel = null;
try {
System.out.println("File receiver listening at port: " + RunningConfiguration.FILE_PORT);
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(RunningConfiguration.FILE_PORT));
socketChannel = serverSocketChannel.accept();
System.out.println("Connection established...." + socketChannel.getRemoteAddress());
} catch (IOException e) {
e.printStackTrace();
}
return socketChannel;
}
/**
* Reads the bytes from socket and writes to file
*
* #param socketChannel
*/
public void readFileFromSocket(SocketChannel socketChannel) {
RandomAccessFile aFile = null;
try {
aFile = new RandomAccessFile(this.fileName, "rw");
ByteBuffer buffer = ByteBuffer.allocate(1024);
FileChannel fileChannel = aFile.getChannel();
while (socketChannel.read(buffer) > 0) {
buffer.flip();
fileChannel.write(buffer);
buffer.clear();
}
// Thread.sleep(1000);
fileChannel.close();
System.out.println("End of file reached..Closing channel");
socketChannel.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}/*} catch (InterruptedException e) {
e.printStackTrace();
}*/
}
You need to send the length, and probably the name, ahead of the file, so the receiver knows when to stop. The receiver has to make sure to only read exactly that many bytes, which may require reducing the limit on the last read. In addition your copy loops are incorrect:
while (inChannel.read(buffer) > 0) {
buffer.flip();
socketChannel.write(buffer);
buffer.clear();
}
This doesn't necessarily work correctly at end of stream. It should be:
while (inChannel.read(buffer) >= 0 || buffer.position() > 0) {
buffer.flip();
socketChannel.write(buffer);
buffer.compact(); // NB compact(), not clear()
}
noting again that they will need further modification as described above.

My socket isn't sending or receiving bytearrays

I'm trying to send bytes and receive them over my socket connection but they're not doing either. I'm not sure if its a problem to do with the way i'm sending the bytes and strings or because I don't know how to read from server and client.
Client
public class Client implements Runnable {
private Socket socket;
private ByteArrayOutputStream buffer;
private OutputStream output;
private Stage stage;
public Client() {
try {
this.socket = new Socket("localhost", 1337);
this.socket.setTcpNoDelay(true);
this.socket.setKeepAlive(true);
this.output = this.socket.getOutputStream();
InputStream input = this.socket.getInputStream();
this.buffer = new ByteArrayOutputStream();
Thread connection = new Thread(this);
connection.start();
this.sendPacket(0, ByteBuffer.allocate(16 + "TEST".length()).putInt("TEST".length()).put("TEST".getBytes(Constants.UTF8)).array());
System.out.println("[CLIENT] Successfully connected to server.");
} catch (Exception e) {
IOUtils.output("[CLIENT] Error when connecting to server.");
System.exit(1337);
}
}
#Override
public void run() {
try {
while (this.connected()) {
byte[] bytes = this.buffer.toByteArray();
Constants.received += bytes.length;
if (bytes.length < 8) return;
ByteBuffer cbuf = ByteBuffer.wrap(bytes);
int size = cbuf.getInt();
int id = cbuf.getInt();
if (bytes.length < size + 8) continue;
byte[] data = Arrays.copyOfRange(bytes, 8, 8 + size);
this.processPacket(id, data);
this.buffer.close();
(this.buffer = new ByteArrayOutputStream()).write(bytes, 8 + size, bytes.length - 8 - size);
}
System.out.println("[CLIENT] Disconnected from server.");
System.exit(1337);
} catch (Exception e) {
e.printStackTrace();
}
}
private void processPacket(int id, byte[] bytes) {
ByteBuffer data = ByteBuffer.wrap(bytes);
if (id == 0) {
System.out.println("Received packet from server with id 0");
} else if (id == 1) {
System.out.println("Received packet from server with id 1");
}
}
private void sendPacket(int id, byte[] data) {
try {
ByteBuffer bytebuffer = ByteBuffer.allocate(8 + data.length);
bytebuffer.putInt(data.length);
bytebuffer.putInt(id);
bytebuffer.put(data);
byte[] bytes = bytebuffer.array();
Constants.sent += bytes.length;
this.output.write(bytes);
this.output.flush();
} catch (IOException e) {
try {
socket.close();
} catch (IOException io) {
IOUtils.output("[CLIENT] Error with client.");
System.exit(1337);
}
}
}
private boolean connected() {
return this.socket.isConnected() && !this.socket.isInputShutdown() && !this.socket.isOutputShutdown() && !this.socket.isClosed();
}
}
ServerHandler
public class Handler implements Runnable {
private Socket socket;
private ByteArrayOutputStream buffer;
private OutputStream output;
public Handler(Socket socket) {
this.socket = socket;
try {
this.output = this.socket.getOutputStream();
InputStream input = this.socket.getInputStream();
this.buffer = new ByteArrayOutputStream();
Thread connection = new Thread(this);
connection.start();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
IOUtils.output("[HANDLER] Connection from " + socket.getInetAddress());
while (connected()) {
byte[] bytes = this.buffer.toByteArray();
if (bytes.length < 8) return;
ByteBuffer buffer = ByteBuffer.wrap(bytes);
int size = buffer.getInt();
int id = buffer.getInt();
if (bytes.length < size + 8) continue;
byte[] data = Arrays.copyOfRange(bytes, 8, 8 + size);
this.processPacket(id, data);
this.buffer.close();
(this.buffer = new ByteArrayOutputStream()).write(bytes, 8 + size, bytes.length - 8 - size);
}
IOUtils.output("[HANDLER] Client ended connection - " + socket.getInetAddress());
} catch (Exception e) {
e.printStackTrace();
}
}
private void sendPacket(int id, byte[] data) {
try {
ByteBuffer bytebuffer = ByteBuffer.allocate(8 + data.length);
bytebuffer.putInt(data.length);
bytebuffer.putInt(id);
bytebuffer.put(data);
byte[] bytes = bytebuffer.array();
this.output.write(bytes);
this.output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void processPacket(int id, byte[] bytes) {
ByteBuffer data = ByteBuffer.wrap(bytes);
if (id == 0) {
IOUtils.output("Recieved packet with id 0");
} else if (id == 1) {
//TODO: authenticate user.
}
}
private boolean connected() {
return this.socket.isConnected() && !this.socket.isInputShutdown() && !this.socket.isOutputShutdown() && !this.socket.isClosed();
}
}
Server
public class Server implements Runnable {
private int port;
private ServerSocket sock;
public Server(int port) {
this.port = port;
launch();
}
private void launch() {
this.run();
}
#Override
public void run() {
try {
sock = new ServerSocket(port);
System.out.println("[SERVER] Server started");
while(!sock.isClosed()) {
new Handler(sock.accept());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I think this problem might be with ByteArrayOutputStream. I wanted to use ByteBuffer because I heard it was much faster than normal DataInput and output streams.
You are never calling Socket#read inside of your run method... If you dont read anything you dont have anything to work with in your loop, even when you are connected!
Take a look at this Tutorial about Sockets:
https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
Your server code should use ServerSocket instead of Socket. Socket is used to represent Client Socket objects in Java.

Connection Refused - Java Client/Server

I'm trying to create a java push server model for testing on my own machine, this won't be used to connect external clients as the server and client will be on the same machine. After the client connects on the port specified by he/she, they should send a message of their choice that will be sent back to them, and any other clients connected to the same port.
The problem I'm having is i receive a java.net.ConnectException: Connection refused: connect when this is attempted. Below is the client and the server.
Edit: I've taken the time to ensure that the necessary ports are open too, and even disabled my firewall, but to no avail.
Server:
class MainServer {
// port that oir server is going to operate on
final static int port = 1234;
public static void main(String[] args) {
// this is going to model the server for the moment
System.out.println("Server has been started...");
Buffer<Messages> store = new Buffer<Messages>(10);
new Writer(store).start();
try {
ServerSocket serve = new ServerSocket(port);
while(true) {
// wait for server request
Socket socket = serve.accept();
// start thread to service request
new ServerThread(socket,store).start();
}
} catch(IOException e) {e.printStackTrace();}
}
}
class ServerThread extends Thread {
Socket socket;
Buffer<Messages> buffer;
public ServerThread(Socket s, Buffer<Messages> b) {
socket = s;buffer = b;
}
public void run() {
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
int port = in.readInt();
System.out.println("Port: "+port);
Messages ms = new Messages(port);
// Read message as string from user
String message = in.readUTF();
int k = in.readInt();
while(k != -1) {
// Add message to array
// read next message
ms.add(message);
message = in.readUTF();
}
// close connection
socket.close();
// add message to buffer
buffer.put(ms);
} catch(IOException e) {e.printStackTrace();}
}
}
class Writer extends Thread {
Buffer<Messages> buffer;
public Writer(Buffer<Messages> m) {buffer = m;}
public void run() {
while(true) {
Messages dp = buffer.get();
dp.write();
}
}
}
class Buffer <E> {
/**
* Producer & Consumer Buffer
*/
private int max;
private int size = 0;
private ArrayList<E> buffer;
private Semaphore empty; //control consumer
private Semaphore full; // control producer
private Lock lock = new ReentrantLock();
public Buffer(int s) {
buffer = new ArrayList<E>();
max = s;
empty = new Semaphore(0);
full = new Semaphore(max);
}
// add data to our array
public void put(E x) {
try {
full.acquire();
} catch(InterruptedException e) {}
// sync update to buffer
lock.lock();
try {
buffer.add(x);
size++;
empty.release();
} finally {lock.unlock();}
}
public E get() {
try {
empty.acquire();
} catch(InterruptedException e) {}
// sync uodate on buffer
lock.lock();
try {
E temp = buffer.get(0);
buffer.remove(0);
size--;
full.release();
return temp;
} finally {lock.unlock();}
}
}
final class Messages {
private final int port;
private final ArrayList<String> data = new ArrayList<String>();
public Messages(int p) {port = p;}
void add(String message) {
data.add(message);
}
void write() {
try {
Socket socket;
socket = new Socket(InetAddress.getLocalHost(),port);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// write message
out.write(data.size());
for(String k : data) {out.writeUTF(k);}
out.flush();
socket.close();
} catch(IOException e) {e.printStackTrace();}
}
}
Client:
class Client {
final static int nPort = 1234;
static int serverPort;
public static void main(String[] args) {
// this class and those present in it
// will model the client for assignment 8
Scanner in = new Scanner(System.in);
System.out.println("Please enter the messageboard number: ");
serverPort = in.nextInt();
System.out.println("Please type your message: ");
String msg = in.next();
Listener lis = new Listener(serverPort);
lis.start();
boolean go = true;
while(go) {
try {
Thread.sleep(2000);
} catch(InterruptedException e) {}
write(serverPort, msg);
System.out.println("Continue: 0/1");
int x = in.nextInt();
if(x == 0)go = false;
}
System.exit(0);
}
static void write(int port, String msg) {
try {
Socket socket;
socket = new Socket(InetAddress.getLocalHost(),port);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// send message to port
out.writeInt(port);
out.writeUTF(msg);
// write sentinal after message has been written and close socket
out.writeInt(-1);
out.flush();
socket.close();
} catch(IOException e) {System.out.println(e);}
}
}
class Listener extends Thread {
private int port;
volatile boolean go;
public Listener(int p) {p = port;}
public void run() {
try {
ServerSocket serversock = new ServerSocket(port);
while(go) {
Socket socket = serversock.accept();
DataInputStream in = new DataInputStream(socket.getInputStream());
// Read the message
while(in.available() > 0) {
String k = in.readUTF();
System.out.print(k+" ");
}
System.out.println();
socket.close();
}
} catch(IOException e) {go = false;}
}
}
Turns out i had a wrong assignment in my Listener class. I had p = port instead of port = p.
Solved. Through my own stupidity.
The hostname you are connecting to is localhost so you are assuming the server is on the same machine. If you need to connect to a different machine, you need to specify the host you want it to connect to.
Try changing socket = new Socket(InetAddress.getLocalHost(),port);
to
socket = new Socket(*IP OF SERVER (127.0.0.1 if same machine)*, port);

Java: Send and receive byte array

Well, I want to write a simple java client-server-programme, which exchanges byte arrays over tcp-sockets.
/* Server */
public class Server {
private ServerSocket Server = null;
private Socket Client = null;
public static void main(String[] args) {
Server A = new Server();
A.runServer();
A.listenServer();
}
public void runServer() {
try {
Server = new ServerSocket(1234);
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
System.exit(-1);
}
}
public void listenServer() {
try {
while (true) {
System.out.println("Waiting...");
Client = Server.accept();
System.out.println("Got something new");
readMessage(Client);
}
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
}
}
public byte [] readMessage (Socket socket) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1];
int len = -1;
while((len = socket.getInputStream().read(buf))!=-1){
baos.write(buf, 0, len);
}
for (int i=0; i<baos.toByteArray().length; i++) {
System.out.println(baos.toByteArray()[i]);
}
return baos.toByteArray();
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
}
return null;
}
public void writeMessage (Socket socket, String Message) {
try {
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
printWriter.print(Message);
printWriter.flush();
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
}
}
}
/* Client */
public class Client {
public static void main(String[] args) {
Client B = new Client();
B.runClient();
}
public void runClient () {
Socket socket = null;
try {
socket = new Socket("127.0.0.1", 1234);
}
catch (Exception e) {
System.out.println("Client fault: "+e.getMessage());
}
byte [] Tmp = new byte[10];
for (int i=0; i<Tmp.length; i++) {
Tmp[i] = 1;
}
writeMessage(socket, Tmp);
for (int i=0; i<10; i++) {
byte [] Message = readMessage(socket);
System.out.println(Message);
}
}
public void writeMessage (Socket socket, byte [] myByteMessage) {
try {
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
dos.write(myByteMessage, 0, myByteMessage.length);
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
printWriter.print(myByteMessage);
printWriter.flush();
}
catch (Exception e) {
System.out.println("Could not send data over TCP");
return;
}
}
public byte [] readMessage (Socket socket) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1];
int len = -1;
while((len = socket.getInputStream().read(buf))!=-1){
baos.write(buf, 0, len);
}
for (int i=0; i<baos.toByteArray().length; i++) {
System.out.println(baos.toByteArray()[i]);
}
System.out.println("Test");
return baos.toByteArray();
}
catch (Exception e) {
System.out.println("Server fault: "+ e.getMessage());
}
return null;
}
}
The problem is, that the client send something to the server but the server doesn't receive anything, so he hangs at the readMessage function.
On the other hand, the client receive some weird stuff, but not the response from the server.
The server receives bytes, but it never leaves the while loop because read() never returns -1. read() returns -1 when the end of the stream is reached. And that happens only when the client closes the socket output stream. Since the client never closes the output stream, the server keeps waiting for the more bytes to come.
Side note: your code is hard to read because you don't respect the standard Java naming conventions: variables start with a lowercase letter.

Categories

Resources