I'm working on a simple Application.
I'm trying to understand my the exception, but i just can't.
How to reproduce:
Starting Netty Server
Connecting to Netty Server with Client -> Valid Response, Server + Client working fine.
Client closed (0 Channels are active, proven by a debug thread)
NEW Client tries to read -> Error: java.net.SocketException: Software caused connection abort: recv failed
Restarting Server, goto 2.
Server source:
public class Server {
private final int port;
public Server(int port) {
this.port = port;
}
public void run() throws Exception {
final EventLoopGroup boss = new NioEventLoopGroup();
final EventLoopGroup worker = new NioEventLoopGroup();
try {
final ServerBootstrap b = new ServerBootstrap();
b.group(boss, worker)
.channel(NioServerSocketChannel.class)
.childHandler(new SocketChannelInitializer());
final ChannelFuture f = b.bind(port).sync();
final ChannelFuture c = f.channel().closeFuture();
System.out.println("- DONE -");
c.sync();
} finally {
worker.shutdownGracefully();
boss.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 8080;
}
new Server(port).run();
}
}
My Initialisizer:
public static final String PACKET = "packet";
public static final String STRING_DECODER = "stringDecoder";
public static final String NETWORK_HANDLER = "networkHandler";
#Override
public void initChannel(SocketChannel ch) throws Exception {
System.out.println("Creating new Channel!");
final ChannelPipeline p = ch.pipeline();
p.addLast(NETWORK_HANDLER, new NetworkHandler());
p.addLast(STRING_DECODER, new StringDecoder(CharsetUtil.UTF_8));
p.addLast(new Testdecoder());
p.addLast(new ChatAdapter());
}
Server DOES process the request, but it cannot read a correct Message.
My Client:
public static void main(String[] args) throws IOException {
final Socket s = new Socket();
s.connect(new InetSocketAddress("localhost", 8080));
final InputStream is = s.getInputStream();
final OutputStream os = s.getOutputStream();
os.write(0x0);
os.write("username".getBytes(CharsetUtil.UTF_8));
os.flush();
System.out.println("!");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b = new byte[4096];
while (true) {
int n = is.read(b);
if (n < 0) {
break;
}
baos.write(b, 0, n);
}
byte data[] = baos.toByteArray();
System.out.println(new String(data, CharsetUtil.UTF_8));
System.out.println("- DONE -");
s.close();
}
Using Netty 4.0.23.Final
Example Application:
https://github.com/BjoernAkAManf/Chat
Startup Server.main(String[] args) and run Client.main(String[] args) twice. You'll get a proper output first. 2nd run will fail.
I tested anything i could possibly think of. Really appreciate help here. Thank you
Despite my first Idea this is not a 'real' server issue, nor is it an issue with netty. The Client uses oio (java.IO) Sockets to connect to a Nio Netty Server.
Changing NioEventLoopGroup to OioEventLoopGroup and NioServerSocketChannel to OioServerSocketChannel resolves this weird issue.
Furthermore one may change the Client to work with Nio. In the following Example i will use java.nio:
final SocketChannel c = SocketChannel.open();
c.connect(new InetSocketAddress("localhost", 8007));
final ByteBuffer buf = ByteBuffer.allocate(5);
// fill Buffer
buf.put((byte) 0x0);
buf.put("Test".getBytes(CharsetUtil.UTF_8));
// Flip buffer
buf.flip();
// Write buffer to socket
while (buf.hasRemaining()) {
c.write(buf);
}
System.out.println("Reading ...");
// Read
buf.flip();
while (true) {
int n = c.read(buf);
if (n < 0) {
break;
}
final String d = new String(buf.array());
if(!d.isEmpty()) System.out.println("'" + d + "'");
buf.clear();
}
// Finish Programm
System.out.println("- DONE -");
c.close();
That example works perfectly fine. Obviously the problem was right infront of my eyes.
Now it's fixed.
This can be solved by providing Thread.sleep(time) before you close the server and start again.
Related
I'm trying to code an instant messaging system... Initially, I'm doing it this way, and once I get it to work I'll add the GUI.
Once a client sends a message to the server, the server is supposed to display it to all the other clients. How can I do that? I've been trying a few things but it keeps displaying only to the client that sent the message...
Thanks in advance!
SERVER
import java.io.*;
import java.net.*;
class Server {
//one per server
static int port = 3000;
private int backlog = 100;
ServerSocket main;
static DataOutputStream dataOut;
static DataInputStream dataIn;
static String scannerMessage;
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static class MailServer extends Thread {
//one per client
static int index;
String name = Client.name;
public MailServer(int index, DataInputStream in, DataOutputStream out) {
Server.dataIn = in;
Server.dataOut = out;
this.index = index; // thread index, one per client
}
public void run() {
while (true) {
try {
String receivedMessage = dataIn.readUTF();
//print receivedMessage to all clients
} catch (Exception e) {
break;
}
}
}
}
public Server(int port) throws Exception {
this.main = new ServerSocket(port);
}
// start a serve
public void serve() throws Exception {
int index = 1;
while (true) {
Socket socket = this.main.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dataIn = new DataInputStream(in);
DataOutputStream dataOut = new DataOutputStream(out);
// handle the connection
// keep reading using an infintite loop
System.out.println("Handling connection to Client " + index + "...");
(new MailServer(index, dataIn, dataOut)).start();
index += 1; // add one every time a new client is added
}
}
public static void main(String[] args) throws Exception {
Server s = new Server(port);
System.out.println("Serving....");
s.serve();
}
}
CLIENT
import java.io.*;
import java.net.*;
class Client {
static String hostname = "127.0.0.1";
static int port = Server.port;
static Socket socket;
static String name;
static class Sender extends Thread {
DataOutputStream dataOut;
public Sender(DataOutputStream dataOut) {
this.dataOut = dataOut;
}
public void run() {
while(true) {
//get a message from the user
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String message = br.readLine();
dataOut.writeUTF(message);
dataOut.flush();
} catch(Exception e) {
break;
}
}
}
}
static class Receiver extends Thread {
DataInputStream dataIn;
public Receiver(DataInputStream dataIn) {
this.dataIn = dataIn;
}
public void run() {
while(true) {
try {
//RECEIVE A MESAGE FROM THE SERVER (ending in \n)
String msg = dataIn.readUTF();
while (msg != null) {
System.out.println(msg);
msg = dataIn.readUTF();
}
} catch(Exception e) {
break;
}
}
}
}
//client will require host name and the port
public Client(String hostname, int port) throws Exception {
socket = new Socket(hostname, port);
}
public void connect() throws Exception {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dataIn = new DataInputStream(in);
DataOutputStream dataOut = new DataOutputStream(out);
//handle the connection
System.out.println("Handling connection to server...");
Thread sender = new Sender(dataOut);
Thread receiver = new Receiver(dataIn);
sender.start();
receiver.start();
sender.join();
receiver.join();
System.out.println("Client " + Server.MailServer.index);
System.out.println("----------------------");
}
public static void main(String[] args) throws Exception {
Client c = new Client(hostname, port);
c.connect();
}
}
Update: I created a list of all the MailServer objects and then iterated through them to send the message to all the clients, as JP Moresmau suggested... but now the first Client to send something receives all the outputs. Why is this? How can I fix it... ? Thank you, and sorry if my questions seem too obvious or dumb, I'm still a Java noob:(
SERVER - UPDATED
package csci2020_assignment51;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
class Server {
//one per server
static int port = 3000;
private int backlog = 100;
ServerSocket main;
static DataOutputStream dataOut;
static DataInputStream dataIn;
static String scannerMessage;
static List<MailServer> mailServers = Collections.<MailServer>synchronizedList(new ArrayList<MailServer>());
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static class MailServer extends Thread {
//one per client
static int index;
String name = Client.name;
public MailServer(int index, DataInputStream in, DataOutputStream out) {
Server.dataIn = in;
Server.dataOut = out;
this.index = index; // thread index, one per client
}
public void run() {
while (true) {
try {
String receivedMessage = dataIn.readUTF();
String outputMessage = "Client " + index + " said: " + receivedMessage;
//print receivedMessage to all clients
for (MailServer mailserver : mailServers) {
dataOut.writeUTF(outputMessage);
}
} catch (Exception e) {
break;
}
}
}
}
public Server(int port) throws Exception {
this.main = new ServerSocket(port);
}
// start a serve
public void serve() throws Exception {
int index = 1;
while (true) {
Socket socket = this.main.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
DataInputStream dataIn = new DataInputStream(in);
DataOutputStream dataOut = new DataOutputStream(out);
// handle the connection
// keep reading using an infintite loop
System.out.println("Handling connection to Client " + index + "...");
MailServer mailServer = new MailServer(index, dataIn, dataOut);
mailServer.start();
mailServers.add(mailServer);
dataOut.writeUTF("Client " + index);
index += 1; // add one every time a new client is added
}
}
public static void main(String[] args) throws Exception {
Server s = new Server(port);
System.out.println("Serving....");
s.serve();
}
}
Have a static list of all the MailServer objects you create
static List<MailServer> servers=Collections.<MailServer>synchronizedList(new LinkedList<MailServer>);
...
MailServer s=new MailServer(index, dataIn, dataOut);
servers.add(s);
s.start();
Then loop through them all when one of them receives a message, and for all expect the receiver, write the message to their output.
The big problem in your code is that dataOut and dataIn are unique! You need to move them to the MailServer class. Each MailServer talks to one specific client and hence needs to have their own streams.
static class MailServer extends Thread {
DataOutputStream dataOut;
DataInputStream dataIn;
And your notification loop becomes:
for(MailServer mailServer:mailServers){
if (mailServer!=this){
mailServer.dataOut.writeUtf(...);
}
}
I also don't understand how you expect to get the Client.name in the server, since Client runs on another machine... Get rid of that for now.
I have set up my webserver, for the time being only localhost, at port 8080 for testing.
public class WebServer {
static int port = 8080; //not the final port
static String ip = "127.0.0.1"; // not the final IP
public static void main(String[] args) throws IOException {
InetSocketAddress i = new InetSocketAddress(ip, port); //localhost - 127.0.0.1
HttpServer server = HttpServer.create(i, 0);
server.createContext("/tester", new testHandler("index.html"));
server.createContext("/startpage", new PagesHandler());
server.createContext("/online", new OnlineHandler());
server.createContext("/logfile", new LogFileHandler());
server.setExecutor(null);
server.start();
}
I have a seperate handler for each of the page references, which basicly does the same thing.
Example for the PagesHandler()
static class PagesHandler implements HttpHandler {
String content = "public/";
#Override
public void handle(HttpExchange he) throws IOException {
File file = new File(content + "index.html");
byte[] bytesToSend = new byte[(int) file.length()];
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
bis.read(bytesToSend, 0, bytesToSend.length);
} catch (IOException ie) {
ie.printStackTrace();
}
he.sendResponseHeaders(200, bytesToSend.length);
try (OutputStream os = he.getResponseBody()) {
os.write(bytesToSend, 0, bytesToSend.length);
}
}
}
This makes me have a lot of redundant code, which i really dont see the need for.
My question is. I am guessing there is a way to parse the handler with a filename, instead of the hardcodeded filename in File file,
But how would i go about doing that?
would a constructor of the handler with a String parameter for the filename do?
like so
public pagesHandler(String fileName){
}
and in the main something like this:
server.createContext("/tester", new testHandler("index.html"));
And if not how would i go about reducing the rudandant code ?
The Android app is behind a NAT (3G connection) , while the server is on a public IP.
The Android app can connect to the server socket and send data (via Socket/TCPclient on android) but the server cannot connect to the Android port because of the NATs
(server getting "... has failed to respond "ip_adress_of_android : port_that_is_open_and_listening_on_android".
Is there anyway to overcome this, or some parameters I can use in order for the server connection attempt to reach it's destination over the NATs without using a custom library? - or could you please point me to an easy to implement method, I don't have time to study and integrate a complicated 3rd party library
Here is a sample of how my server code works:
int port_server, port_android; // used to declare used ports by the server and android
Socket server_socket, client_socket; //sockets used to receive and send data
server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server_socket.Bind(new IPEndPoint(IPAddress.Any, port_server));
server_socket.Listen(0);
public void listen()
{
server_socket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
private void AcceptCallback(IAsyncResult AR)
{
client_socket = server_socket.EndAccept(AR);
buffer = new byte[client_socket.ReceiveBufferSize];
client_socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null);
}
private void ReceiveCallback(IAsyncResult AR)
{
listen(); // to continue listening to the port
// code that does something with the data
send_string("Take this"); // sends a string to android
}
public void send_string(string notif)
{
string ip_client = client_socket.RemoteEndPoint.ToString();
string ip_client2 = (ip_c.Split(':'))[0];
TcpClient client = new TcpClient(ip_client, port_android);
Byte[] notifi = System.Text.Encoding.ASCII.GetBytes(notif);
NetworkStream stream = client.GetStream();
stream.Write(notifi, 0, notifi.Length);
stream.Close();
client.Close();
}
I should note that they work both ways when on a LAN, so the code is working, I only need to modify is so that it can reach android targets over NATs.
Something like this
class Program
{
int port_server = 42424;
Socket server_socket;
public Program()
{
server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server_socket.Bind(new IPEndPoint(IPAddress.Any, port_server));
server_socket.Listen(0);
}
public void Listen()
{
while (true)
{
var client = server_socket.Accept();
var buffer = new byte[client.ReceiveBufferSize];
client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), Tuple.Create(client, buffer));
}
}
private void ReceiveCallback(IAsyncResult AR)
{
var state = (Tuple<Socket, byte[]>)AR.AsyncState;
var client = state.Item1;
var buffer = state.Item2;
byte[] notifi = System.Text.Encoding.ASCII.GetBytes("Take this");
client.Send(notifi);
client.Close();
}
static void Main(string[] args)
{
var programm = new Program();
programm.Listen();
}
}
client part
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 42424));
client.Send(new byte[] {1, 2, 3}, SocketFlags.None);
byte[] bt = new byte[256];
client.Receive(bt, 256, SocketFlags.None);
}
The code works fine when I close the client just after sending one instruction. But when I want a client and server connection to persist, so that the client can send multiple instructions to the server one after another, I get a Null pointer exception at the server and the message java.net.SocketException: Socket is closed at the client. This happens after the client sends a file to the server and the server successfully receives it. Need help. The error occurs at the Connection class code line switch(clientMsg). It seems to me that for some reason the BufferedReader in goes null, but I might be mistaken about that. The code is as follows. Thanks.
Server
public class server {
private static ServerSocket serverSocket;
private static Socket socket = null;
public static void print(Object s) {
System.out.println(s);
}
#SuppressWarnings("resource")
public static void main (String args[]) throws IOException {
System.out.print("Specify listening port: ");
Scanner _a = new Scanner(System.in);
int a = _a.nextInt();
try{
serverSocket = new ServerSocket(a);
}
catch(IOException e) {
System.out.println(e);
}
while (true) {
try {
socket = serverSocket.accept();
print("Connected to " + socket);
Thread client = new Thread(new Connection(socket));
client.start();
}
catch (IOException e) {
print(e);
}
}
}
}
Connection
public class Connection implements Runnable {
public static void print(Object s) {
System.out.println(s);
}
private Socket socket;
private BufferedReader in = null;
public Connection(Socket client) {
this.socket = client;
}
#Override
public void run(){
try {
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String clientMsg;
while (true) {
clientMsg = in.readLine();
switch (clientMsg) {
case "1":
receiveFile(); //method code not included
break;
default:
print("Command not recognized");
break;
}
//in.close();
}
}//try run()
catch (IOException e) {
print(e);
}
}
Client
public class client {
private static Socket connectToServer;
private static String fileName;
private static BufferedReader keybrdIn;
private static PrintStream msgToServer;
public static void println(Object e) {
System.out.println(e);
}
public static void print(Object e) {
System.out.print(e);
}
public static void main(String args[]) throws IOException{
try{
print("Enter IP: ");
String ip = new Scanner(System.in).nextLine();
print("Enter port: ");
int port = new Scanner(System.in).nextInt();
connectToServer = new Socket(ip, port);
keybrdIn = new BufferedReader(new InputStreamReader(System.in));
}catch(IOException e) {
println(e);
}
msgToServer = new PrintStream(connectToServer.getOutputStream());
while (true) {
try {
switch(Integer.parseInt(action())) { //action() method code not included
case 1:
msgToServer.println("1");
sendFile();
break;
default:
println("Invalid input");
break;
}
}catch (IOException e) {
println(e);
}
}
}
sendFile()
public static void sendFile() throws IOException {
print("Enter file name: ");
fileName = keybrdIn.readLine();
File file = new File(fileName);
byte[] bytearray = new byte[8192];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os = connectToServer.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(file.getName());
int count;
while ((count = dis.read(bytearray)) > 0){
dos.write(bytearray, 0, count);
}
dis.close();
dos.flush();
dos.close();
}
receiveFile()
public void receiveFile() {
try {
int count;
DataInputStream clientFileStream = new DataInputStream(socket.getInputStream());
String fileName = clientFileStream.readUTF();
OutputStream fileOutput = new FileOutputStream("_" + fileName);
byte[] mybytearray = new byte[8192];
BufferedOutputStream bos = new BufferedOutputStream(fileOutput);
System.out.println("Downloading " + fileName + " ...");
//outToClient().writeBytes("Uploading. Please wait...\n");
while ((count = clientFileStream.read(mybytearray)) > 0){
bos.write(mybytearray, 0, count);
}
fileOutput.close();
bos.close();
clientFileStream.close();
}
catch (IOException e) {
print(e);
}
}
In sendFile(), you close the data output stream which closes your underlying connection's output stream.
According to the documentation of Socket.getOutputStream():
"Closing the returned OutputStream will close the associated socket".
Since you already closed stream, it will also close socket as well as Eyal mentioned. However, at the moment you close the stream, server side will aware of that and return -1 for read() results.
So, even if you didn't specify file length at beginning, this will generally works well.
However, since you already closed stream, you can't reuse it no matter what. To fix this issue, probably you need to change your Client class so that Client should create socket connection, send files, close socket. That's one lifecycle of opened client socket.
Or maybe in while loop of Client class, 1) take ip, port, and filename to send 2) Create new Thread and provide those information so let thread open connection, send file, close connection 3) and in the meantime, client while() can keep take next ip, port, and filename to send from the user. By doing this, you don't need to make client program wait until file transfer to be completed.
Regarding the NPE in the server, readLine() returns null at end of stream. You are ignoring it. You should be testing for it immediately after the call, and if null close the socket and exit the read loop.
Currently I am working on a server/client application which sends data using java with Runnable and threads. The problem is that the client is sending the data and when the server starts to read it the client has already finished and closed the connection which on the server side only a partially of the data is arrived, can they be setup to be synchronized?
this is the client:
private void ConnectionToServer(final String ipAddress, final int Port) {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
#Override
public void run() {
try {
socket = new Socket(ipAddress, Port);
bos = new BufferedOutputStream(socket.getOutputStream());
dos = new DataOutputStream(socket.getOutputStream());
File f = new File("C:/Users/lukeLaptop/Downloads/RemoveWAT22.zip");
String data = f.getName()+f.length();
byte[] b = data.getBytes();
sendBytes(b, 0, b.length);
dos.flush();
bos.flush();
bis.close();
dos.close();
//clientProcessingPool.submit(new ServerTask(socket));
} catch (IOException ex) {
Logger.getLogger(ClientClass.class.getName()).log(Level.SEVERE, null, ex); } finally {
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
public void sendBytes(byte[] myByteArray, int start, int len) throws IOException {
if (len < 0) {
throw new IllegalArgumentException("Negative length not allowed");
}
if (start < 0 || start >= myByteArray.length) {
throw new IndexOutOfBoundsException("Out of bounds: " + start);
}
// Other checks if needed.
// May be better to save the streams in the support class;
// just like the socket variable.
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
dos.writeInt(len);
if (len > 0) {
dos.write(myByteArray, start, len);
}
}
server code:
private void acceptConnection() {
try {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
#Override
public void run() {
try {
ServerSocket server = new ServerSocket(8080);
while (true) {
socket = server.accept();
System.out.println("Got a client !");
bis = new BufferedInputStream(socket.getInputStream());
dis = new DataInputStream(socket.getInputStream());
String data = readBytes().toString();
System.out.println(data);
bos.close();
dis.close();
//clientProcessingPool.submit(new ClientTask(socket));
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
} catch (Exception io) {
io.printStackTrace();
}
}
public byte[] readBytes() throws IOException {
// Again, probably better to store these objects references in the support class
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in);
int len = dis.readInt();
byte[] data = new byte[len];
if (len > 0) {
dis.readFully(data);
}
return data;
}
You mixed up many things:
Variables start most of the time with a lowercase letter, e.g. int port, int ipAddress
Classes start with a uppercase letter, e.g. Client, Server
only open one Data*stream on a socket. new DataInputStream(socket.getInputStream()) or new BufferedInputStream(socket.getInputStream()), but not both
If you need both, chain them: new DataInputStream(new BufferedInputStream(socket.getInputStream()));
KISS (Keep it short & simple)
If you use a DataInputStream, then use the given functionality of sending objects and primitives, e.g. sendUTF(), sendInt(), sendShort(), and so on...
Name your vars right: servertask is a client thread? no
Move long anonymous classes to a new class
Don't use port 8080, this port is used for many other application and will cause problems
example code regarding your example an my advices:
Server
public class Server implements Runnable {
private void acceptConnection() {
Thread serverThread = new Thread(this);
serverThread.start();
}
#Override
public void run() {
try {
ServerSocket server = new ServerSocket(8081);
while (true) {
Socket socket = server.accept();
System.out.println("Got a client !");
// either open the datainputstream directly
DataInputStream dis = new DataInputStream(socket.getInputStream());
// or chain them, but do not open two different streams:
// DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
// Your DataStream allows you to read/write objects, use it!
String data = dis.readUTF();
System.out.println(data);
dis.close();
// in case you have a bufferedInputStream inside of Datainputstream:
// you do not have to close the bufferedstream
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
new Server().acceptConnection();
}
}
description:
main: create a new Server Object, which is a Runnable
acceptConnections: create a Thread
run:
open a Serversocket
wait for a connection
open exactly one stream
read the Data
close the stream and wait for next connection
Client
public class Client {
private static void sendToServer(String ipAddress, int port) throws UnknownHostException, IOException {
Socket socket = new Socket(ipAddress, port);
// same here, only open one stream
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
File f = new File("C:/Users/lukeLaptop/Downloads/RemoveWAT22.zip");
String data = f.getName()+f.length();
dos.writeUTF(data);
dos.flush();
dos.close();
}
public static void main(String[] args) throws UnknownHostException, IOException {
Client.sendToServer("localhost", 8081);
}
}
description (This one is straight forward):
open socket
open DataStream
send Data
flush and close