This is my problem, all the messages sent from the c# client aren't received by the server until that I Shutdown the socket on client side and finally the server receive all data in once time.
c# client side
public static class AsynchronousClient
{
// The port number for the remote device.
private const int port = 8888;
// ManualResetEvent instances signal completion.
private static ManualResetEvent connectDone =
new ManualResetEvent(false);
private static ManualResetEvent sendDone =
new ManualResetEvent(false);
private static ManualResetEvent receiveDone =
new ManualResetEvent(false);
public static Socket client;
// The response from the remote device.
private static String response = String.Empty;
public static void StartClient()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// The name of the
// remote device is "host.contoso.com".
IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1");
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 8888);
// Create a TCP/IP socket.
client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
// Send test data to the remote device.
Send(client, "test connection");
sentDown.WaitOne();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static void Send(Socket client, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None,
new AsyncCallback(SendCallback), null);
}
public static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Java server side
public class Connection_to_port extends Thread {
final static int port = 8888;
private Socket socket;
String message = "";
public static void main(String[] args) {
try {
ServerSocket socketServeur = new ServerSocket(port);
while (true) {
Socket socketClient = socketServeur.accept();
Connection_to_port t = new Connection_to_port(socketClient);
t.start();
System.out.println("Connected to client : " + socketClient.getInetAddress());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public Connection_to_port(Socket socket) {
this.socket = socket;
}
public void run() {
handleMessage();
}
public void handleMessage() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
message = in.readLine();
System.out.println(message);
}
catch (Exception e) {
e.printStackTrace();
}
}
In my client i have to send some data to the server like that
AsynchronousClient.Send(AsynchronousClient.client, "{myjsondata}");
My client is just for sending, not receive.
The problem is, my java server receive nothing ! But the client said it's sent, and i see on Wireshark that's it's send.
When i do
AsynchronousClient.client.Shutdown(SocketShutdown.Both);
Finally i see all my message on the server at the same time. Like if i sent only one message.
The Java side is trying to read a line (you are using readLine).
This method will not return until either there is an end-of-line character, or the stream is closed.
When you shutdown the client, in effect, the stream closes.
Your test message does not include an end-of-line character, so the only way for readLine to return is at the end of stream.
When you write to a socket, the message does not sent, it's saved in buffer until:
Buffer is full
You request to clean/flush the buffer
You shutdown.
Try the following methods:
http://msdn.microsoft.com/en-us/library/system.net.sockets.socketoptionname.aspx
http://angrez.blogspot.co.il/2007/02/flush-socket-in-net-or-c.html
Related
I'm trying to create a TCP client/server that sends and receives messages. My problem right now is that I can't do them both simultaneously. I'm sending a message to the server and reading it just fine, but after each received message to the server, I also want to send back a response to the client acknowledging it.
I'm sending several messages per second to the server, but when I try to re-send a message to the client, it just gets stuck, no message on either end. I can however send in either direction, client to server and server to client, but only one way.
This is the client handler for the server:
public TCPClientHandler(Socket client, int bufferSize) throws IOException {
this.client = client;
messageToClient = new PrintWriter(client.getOutputStream(),true);
recvFromClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
buffer = new byte[bufferSize];
}
#Override
public void run() {
try {
/* Read the data from the client.
* If the message is larger than the server buffer we close the connection.
* If the client closes connection we get exception and we catch it
* at the end.
*/
while (true) {
if (recvFromClient.readLine().getBytes().length > buffer.length){
break;
}
/* Receiving and printing message */
buffer = Arrays.copyOf(recvFromClient.readLine().getBytes(),
recvFromClient.readLine().getBytes().length);
String messageFromClient = new String(buffer,StandardCharsets.UTF_8);
System.out.println("Client message: " + messageFromClient);
messageToClient.println();
/* Sending message to client */
}
} catch (IOException e) {
System.out.println("Connection to client lost...");
} finally {
System.out.println("Connection closed on thread " + Thread.currentThread().getName());
messageToClient.close();
try {
recvFromClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is the client:
public class TCPEchoClient {
/*
Args input
1. Server Address
2. Server Port
3. Socket Buff Size
4. Transfer Rate
5. Message
*/
public void run(String args[]){
try {
// Dummy values
InetAddress host = InetAddress.getByName("localhost");
int serverPort = 4950;
int buffSize = 100;
int transferRate = 5;
String echoMessage = "112312451265214126531456234321";
String receive;
System.out.println("Connection to server on port " + serverPort);
Socket socket = new Socket(host,serverPort);
socket.setReceiveBufferSize(buffSize);
System.out.println("Just connected to " + ocket.getRemoteSocketAddress());
// Writer and Reader to write and read to/from the socket.
PrintWriter writeToServer = new PrintWriter(socket.getOutputStream(),true);
BufferedReader recvFromServer = new BufferedReader(new `InputStreamReader(socket.getInputStream()));`
if (transferRate < 1){
writeToServer.println(echoMessage);
}else {
// Continuously send messages with 1 second between x amount of
// messages, until client is aborted.
while (true) {
for (int i = 0; i < transferRate; i++) {
writeToServer.println(echoMessage);
receive = new String(recvFromServer.readLine().getBytes(), StandardCharsets.UTF_8);
System.out.println(receive);
}
Thread.sleep(1000);
}
}
// Close reader/writer and socket
writeToServer.close();
recvFromServer.close();
socket.close();
} catch (SocketException e){
System.out.println("Socket exception...");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TCPEchoClient client = new TCPEchoClient();
client.run(args);
}
}
I would like to read the messages that are transmitted as bytes, store them in the buffer, and THEN read the message, but so far no success.
Fixed the issue. I moved the receive part inside the client to AFTER the thread sleep.
I'm creating a java chat server that handles multi clients I use this simple code for server
public class Server extends Thread {
ServerSocket serverSocket = null;
Socket socket = null;
private int unique_id;
ArrayList<Clients> cl;
public Server(int port) {
try {
serverSocket = new ServerSocket(port);
cl = new ArrayList<>();
this.start();
} catch (Exception e){
System.out.println("Error 5");
e.printStackTrace();
}
}
#Override
public void run(){
System.out.println("Server Start");
while (true){
try {
socket = serverSocket.accept();
Clients t = new Clients(socket); // add it to thread
cl.add(t);
t.start();
System.out.println("Connected " + String.valueOf(cl.size())); // printed ok
}catch (Exception e){
System.out.println("Error 4");
e.printStackTrace();
}
}
}
public synchronized void SendToAll(String s){ // this function used by client when one of client socket send a message then server send it to all
System.out.println("Sended is excuted"); // excuted normal each time i send a message from client but not send to all
for (int i = 0; i < cl.size(); i++){
cl.get(i).WriteToSocket(s);
}
}
public static void main(String args[]){
int port = 5002;
Server server = new Server(port); // start server
//server.run(); // start connections wait for it
}
class Clients extends Thread { // class extends thread
public Socket socket = null;
DataInputStream input = null; // read input
DataOutputStream output = null; // read output
public int myid = 0; // unique id for each client
public Clients(Socket soc) {
socket = soc;
try {
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
myid = ++unique_id;
System.out.println("Client Start Thread"); // printed ok !
} catch (IOException e){
System.out.println("Error 1");
e.printStackTrace();
}
}
public void WriteToSocket(String s) { // used to write a message to this socket
try {
output.write(s.getBytes());
}catch (IOException e){
System.out.println("Error 2");
e.printStackTrace();
}
}
#Override
public void run() { // run thread function wait for messages from clients
while (true){
try {
String s = input.readLine();
if (s.contains("quite")) {
socket.close();
input.close();
output.close();
cl.remove(this);
this.stop();
}
if (!s.isEmpty()) {
SendToAll(s);// when message come and not empty it use server function to send them to all clients
}
}catch (IOException e){
System.out.println("Error 3");
e.printStackTrace();
}
}
}
}
}
everything works fine when clients connect the server accept the connection and the client thread started
but the problem when I sent a message from the client it didn't received by the server I try my client application in java too with Qt c++ server and it works ?
so what did I do wrong here make the server can't receive the message ?
this my first time in network programming using java
Edit
I solve the NullPointerException the problem was that when client log out I didn't remove his socket from the ArrayList solved by making client before close send message contains quite so when I see it i remove his socket from array list Another Quetiosn Here i don't know how this message sentthe System.out.println() that is in the SendToAll function printed to the screen each time client send a message but why the message not send again to all clients ? actually the main problem is that server can't send the message to all clients in the array list after message comes from one client the problem not solved stell found
Client Code class
public class ClientSocket extends Thread {
public Socket socket = null;
public DataInputStream input = null;
public DataOutputStream output = null;
MainChat chat = null;
public ClientSocket(String ip, int port,MainChat ch) {
try {
socket = new Socket(ip,port);
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
chat = ch;
this.start();
}catch (IOException e){
}
}
#Override
public void run() {
while (true){
try {
String s = input.readLine();
if (!s.isEmpty()){
chat.WriteToScreen(s.trim());
}
}catch (IOException e){
}
}
}
public void WriteToSocket(String s) throws IOException{
output.write(s.getBytes());
}
}
Edit
when i use this code in main the SendToAll function send the message to all clients !! why when i use it from clients class using Thread it not sended to all ?
public static void main(String args[]){
int port = 5002;
Server server = new Server(port); // start server
//server.run(); // start connections wait for it
while (true) {
String s = in.next();
server.SendToAll(s + "\n"); // message sended to all client !!
}
}
The problem is that readLine reads until it finds a line terminator of end of file. This is why it works with other server in QT C++ but not with the Java server.
Please see here:
https://docs.oracle.com/javase/7/docs/api/java/io/DataInput.html#readLine()
https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readLine()
Please note that readLine in DataInputStream is deprecated. You should use BufferedReader to read a line (with readLine) as indicated in the DataInputStream link.
So, add '\n' to the end of the string sent and it will work.
I solve the problem, I am sorry for that it was my fault I forget to add \n in sendToAll function so this what cause the problem so no \n the clients can't read the line because I use readLine in DataInputStream
anyway I try another method to read bytes instead of readLine it's I think it's better especially when you receive UTF-8 char and after that changes from bytes to String
I'm using a server socket to accept clients on the main thread, when a thread is accepted,the clients socket is given to a handler which is started in a new thread to process communications. However, before I start running my server to access clients, it connects to a second server which it must list to and be able to respond to and pass on the messages it gets to it's clients.
Hopefully this image illustrate what I mean:
The small server must be continuously listening for input from the big server, and also able to output responses.
//Default constructor
private smallServer(){}
//method to initialise and start the server
public static void StartServer(int port) throws IOException {
smallServer ss = new smallServer();
ss.bs= new bigServerClient(ss);
Thread nsc_Thread = new Thread(ss.bsc);
bsc_Thread.start();
//accepts clients and starts new thread for them
ss.ServerRun(port);
}
private void ServerRun(int port) throws IOException {
ServerSocket server = new ServerSocket(port);
server.setSoTimeout(50);
while (run) {
Socket client = null;
try {
client = server.accept();
} catch (SocketTimeoutException e) {
}
if (client != null) {
ClientHandler handler = new ClientHandler(client, this);
Thread handleThread = new Thread(handler);
handleThread.start();
}
}
if (!run) {
synchronized (ClientHandler.handlers) {
for (ClientHandler handler : ClientHandler.handlers) {
handler.terminateHandler();
}
}
System.exit(0);
}
}
public void processBigServerCommand(String toProcess) {
System.out.println("RESEAVED: " + toProcess);
}
The big server client(on the small server) then does this:
public class bigServerClient implements Runnable {
private smalsServer ss;
private PrintWriter printer;
private BufferedReader reader;
private Socket socket;
public bigServerClient(smallServer _ss) throws IOException {
ss = _ss;
socket = new Socket("Localhost", 5000);
printer = new PrintWriter(socket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
printer.flush();
SendBigServerMessage("Starting String");
}
private void SendBigServerMessage(String toSend) {
printer.print(toSend);
printer.flush();
}
#Override
public void run() {
try {
while (ss.state()) {
String inputLine;
while ((inputLine = reader.readLine()) != null) {
ss.processBigServerCommand(inputLine);
System.out.println(inputLine);
}
}
} catch (IOException e) {
} finally {
try {
socket.close();
} catch (IOException ex) {
}
}
}
}
From what's above, can anyone see why the big server client isn't responding to the big server when a message is sent? I'm guessing it's something to do with the main thread blocking the second thread, but I'm not sure... Any help would be greatly appreciated.
You lost me in your code...
Simplify it.
Your smallServer (see class names conventions) should have persistent connection to BigServer (effectively it is BigServer client) - you can implement it in your smallServer class, it should connect (once) and open I/O to BigServer (once) and close everything once the connection is terminated.
As your smallServer will handle multiple clients and pass their requests to BigServer there is no guarantee of the order of BigServer responses - you should do something to handle that (maybe pass UUID with requests?)
Simplify your smallServer and make sure that it runs...
I am trying to write a client-server system using Sockets in java, however I cannot seem to read data sent from the server to the client.
Here is the code for the client:
public class ClientSocket
{
Socket clientSocket = null;
PrintWriter out = null;
BufferedReader in = null;
// establish a connection to All Care's server application through socket 4444 (adjust localhost to reflect the IP address that the server
// is being run from)
public ClientSocket()
{
try
{
clientSocket = new Socket("localhost", 4445);
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch (IOException e)
{
System.out.println("Could not connect to All Care Server Application");
}
}
public void closeClientSocket()
{
try
{
clientSocket.close();
}
catch (IOException e)
{
System.out.println("Could not close connection to All Care Server Application");
}
}
public String getMessageFromServer()
{
try
{
String input = in.readLine();
return input;
}
catch (IOException e)
{
System.out.println("Could not read message from server");
}
return "No Data";
}
public void sendMessageToServer(String message)
{
out.write(message);
}
}
And here is the Server code:
public class ArFileServer {
public static void main(String[] args)
{
ServerSocket serverSocket = null;
boolean listening = true;
try
{
serverSocket = new ServerSocket(4445);
// infinite loop to continually listen for connection requests made by clients
while (listening)
{
new ClientConnection(serverSocket.accept()).start();
if (serverSocket != null)
{
System.out.println("Connection to client established");
}
}
serverSocket.close();
}
catch (IOException e)
{
System.out.println("Error could not create socket connection to port");
}
}
}
public class ClientConnection extends Thread
{
private Socket socket = null;
public ClientConnection(Socket socket)
{
super("ClientConnection");
this.socket = socket;
}
// the thread that runs after a connection to the server has been accepted
#Override
public void run()
{
try
{
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
sendMessagetoClient(out, "CONNECTION SUCCESS");
// check login credentials sent from client to the server
// if valid send back their encrypted password, otherwise output a login error message
// wait for user input and then do various processes based on their requests
in.close();
out.close();
socket.close();
}
catch (IOException e)
{
System.out.println("Client socket connection error");
}
}
// sends a message to the client
void sendMessagetoClient(PrintWriter out, String message)
{
out.write(message);
}
// listens for a message from the client
String getMessageFromClient(BufferedReader in)
{
try
{
String input = in.readLine();
return input;
}
catch (IOException e)
{
System.out.println("Could not read message from client");
}
return "No Data";
}
And here is the line of code im using to see if the data is being sent.
System.out.println(clientSocket.getMessageFromServer());
In your sendMessageToClient() method, you need to flush:
void sendMessagetoClient(PrintWriter out, String message)
{
out.write(message);
out.flush();
}
Or, when you create the PrintWriter, use the constructor with autoflush:
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
And when you write, instead of out.write(message) use printf() or println().
There are several problems here.
You are reading lines but you aren't writing lines.
You aren't checking the result of readLine() for null, which means the peer has closed the connection, which means you must do likewise.
You aren't flushing the PrintWriter after you write.
You are closing things in the wrong order. You must close the output writer/stream you have attached to the socket. Doing that flushes it and then closes the input stream/reader and the socket. Doing this in the wrong order loses the flush. Once you've closed the output you don't need the other two closes.
You are using PrintWriter, which swallows exceptions, across a network, where you need to know about exceptions and errors in communication, and you aren't checking for errors either. Use a BufferedWriter.
in the clint code you are not connecting with server socket.
for clint socket connection
socket soc= new socket ("server host ip",port);
I have a chat program. Now the code works for communicate between client and server via command line. But it gives an exception (java.net.SocketException: Socket is closed) while running. Please help me to fix that problem.
In a java chat program,how will the communication be implemented between client and server?
ie.
client<-->server (between server and client)
or
client A<-->server<-->client B (server act as a bridge between two clients)
Is the 2 way communication can be implemented through a single socket?
Are there any other methods ?
How to communicate more than one client simultaneously?
server code
class Server
{
ServerSocket server;
Socket client;
public Server()
{
try
{
server = new ServerSocket(2000);
System.out.println("\tServer Started..........");
while (true)
{
client = server.accept();
Send objsend = new Send(client);
Recive objrecive = new Recive(client);
//client.close();
}
}
catch (Exception e)
{
System.out.println("Exception4 " + e);
}
}
public static void main(String arg[])
{
new Server();
}
}
class Recive implements Runnable
{
Socket client;
public Recive(Socket client1)
{
client=client1;
Thread trsend=new Thread(this);
trsend.start();
}
public void run()
{
ObjectInputStream ois;
Message M=new Message();
try
{
ois = new ObjectInputStream(client.getInputStream());
M = (Message)ois.readObject();
M.display();
ois.close();
}
catch (Exception e)
{
System.out.println("Exception1 " + e);
}
}
}
class Send implements Runnable
{
Socket client;
public Send(Socket client1)
{
client=client1;
Thread trrecive=new Thread(this);
trrecive.start();
}
public void run()
{
Message M=new Message();
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
try
{
System.out.println("Me(server)");
M.strmessage=br.readLine();
ObjectOutputStream oos=new ObjectOutputStream(cli ent.getOutputStream());
oos.writeObject((Message)M);
oos.flush();
oos.close();
}
catch (Exception e)
{
System.out.println("Exception " + e);
}
}
}
client code
class Client
{
public static void main(String arg[])
{
try
{
Send objsend=new Send();
Recive objrecive=new Recive();
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
class Send implements Runnable
{
public Send()
{
Thread trsend=new Thread(this);
trsend.start();
}
public void run()
{
try
{
Message M=new Message();
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
while(true)
{
System.out.println("Me(client)");
M.strmessage=br.readLine();
Socket client=new Socket("localhost",2000);
ObjectOutputStream oos=new ObjectOutputStream(client.getOutputStream());
oos.writeObject((Message)M);
oos.flush();
oos.close();
}
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
class Recive implements Runnable
{
public Recive()
{
Thread trrecive=new Thread(this);
trrecive.start();
}
public void run()
{
try
{
while(true)
{
Socket client=new Socket("localhost",2000);
ObjectInputStream ois=new ObjectInputStream(client.getInputStream());
Message CNE=(Message)ois.readObject();
CNE.display();
ois.close();
}
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
First of all, don't close the streams in every run().
Secondly, check whether port for server which you are using is free.
This program makes your pc both host and server.
import java.io.IOException;
import java.net.*;
public class ClientServer {
static byte[] buffer = new byte[100];
private static void runClient() throws IOException {
byte buffer[] = new byte[100];
InetAddress address = InetAddress.getLocalHost();
DatagramSocket ds=new DatagramSocket();
int pos = 0;
while (pos<buffer.length) {
int c = System.in.read();
buffer[pos++]=(byte)c;
if ((char)c =='\n')
break;
}
System.out.println("Sending " + pos + " bytes");
ds.send(new DatagramPacket(buffer, pos, address, 3000));
}
private static void runServer() throws IOException {
InetAddress address = InetAddress.getLocalHost();
DatagramSocket ds = new DatagramSocket(3000, address);
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
ds.receive(dp);
String s=new String(dp.getData(),0,dp.getLength());
System.out.print(s);
}
public static void main(String args[]) throws IOException {
if (args.length == 1) {
runClient();
} else {
runServer();
}
}
}
also follow this link
There could be multiple places where the exception could be thrown. Without a stack trace it is difficult to state so accurately, as to the cause of failure.
But the root cause, is essentially due to the fact that you are closing the InputStream of the socket in your Receiver threads after reading a message, and closing the OutputStream of the socket in your Sender threads after sending a message. Closing either of these streams will automatically close the socket, so you if attempt to perform any further operation on it, a SocketException will be thrown.
If you need to ensure that your server and client do not shutdown in such an abrupt manner, you'll have to keep reading the InputStream (until you get a special message to shutdown, for instance). At the same time, you'll also have to keep writing to the OutputStream. Two-way communication is definitely possible, and the posted code is capable of the same (if the socket remains open).
If you have to handle multiple clients, you'll need multiple reader and writer threads on the server, each listening on an instance of a Socket returned from ServerSocket.accept(); in simpler words, you need a reader-writer pair listening on a distinct socket on the server for each client. At the moment, multiple clients can connect to the Server, as each incoming connection is provided its own client Socket object on the Server, that is provided to individual reader and writer threads. The main Server thread can continue to receive incoming connections and delegate the actual work to the reader-writer pairs.
chat programms normaly have a server through which all communication goes. The reason is that other wise every client needs to know how to reach every other client. And that doesn't work in the general case.
So you'll have a server, every client registers and talks with the server, which will forward messages to other clients.
Mostly communication is done via HTTP cause this is likely to go through firewalls and proxies. You probably want to read up on long polling if you are planning for anything serious.