I am trying to make an chatprogram in Java, when I send message on the client side the server side gets the message. But when I send from the server side to the client it do not get the message.
I cannot see what I am doing wrong.
The server side code:
private void serverStart(){
textArea.append("Starting server " + " \n");
try {
serverSocket = new ServerSocket(4444);
textArea.append("Waiting for Clients " + " \n");
//Reading message from the client
socket = serverSocket.accept();
textArea.append("Client Connected " + "\n");
//Send message to client
out = new PrintWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true)
{
messageFromClient = in.readLine();
whileChat(messageFromClient);
}
} catch(IOException ioExecption) {
ioExecption.printStackTrace();
}
}
private void whileChat(String messageFromClient) {
showMessage(messageFromClient);
System.out.println("Message from client : " + messageFromClient);
}
protected static void showMessage(final String message) {
SwingUtilities.invokeLater(
new Runnable(){
public void run()
{
Gui.consoleTextArea.append(message + "\n");
}
});
}
public static void sendMessage(String message) {
out.println(message);
showMessage(name + " : " + message + "\n");
}
The Client side :
private void connectToServer() {
try {
socket = new Socket("localhost", 4444);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Thread clientThread = new Thread(new Runnable() {
#Override
public void run() {
try {
// attach to socket's output stream with auto flush turned on
//Send message to the server
out = new PrintWriter(socket.getOutputStream(),
true);
//Get return message from server
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
messageFromServer = in.readLine();
whileChatting(messageFromServer);
} catch (Exception e) {
e.printStackTrace();
}
}
});
clientThread.start();
}
private void whileChatting(String messageFromServer) {
showMessage(messageFromServer);
System.out.println("Message from server to client " + messageFromServer);
}
public static void Send(String msg) {
out.println(name + " : " + msg);
showMessage(name + " : " + msg + "\n");
}
protected static void showMessage(final String message) {
SwingUtilities.invokeLater(
new Runnable(){
public void run(){
Gui.consoleTextArea.append(message);
}
});
}
Hope someone could help me with this problem.
You could perform a flush on the PrintWriter immediately after each println, or even better: Instance the PrintWriter with autoFlush=true:
out = new PrintWriter(socket.getOutputStream(), true);
In this way, each time you call println, printf, or format, the PrintWriter will perform a flush of the buffer at the end.
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
This line is always waiting the client output, and your client also doesn't send message to server.
Attention: both your server and client not read user input.
Related
I made a Chat Application (Server/Client) using Java. Note: The server is ran as its own jar file and each client is ran as its own jar file.
Each client is on their own thread.
Whenever I send messages to the server, each client receives the message, however when I send messages from the client, only the server receives the message. When the client sends a message, I want all connected clients and the server to receive the message so all of the clients can communicate together and with the server as well.
I've looked at multiple posts and videos about this, but most were too confusing for me to understand.
Could someone please help me understand how I can send messages between threads? Thanks!
-- My Code --
Client:
public Client(User user, String address, int port) {
try {
socket = new Socket(address, port);
ClientApplicationUI app = new ClientApplicationUI();
app.setTitle("Chat Application - " + user.getUsername());
app.setVisible(true);
ServerConnection connection = new ServerConnection(socket, app);
output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
new Thread(connection).start();
app.getButton().addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (app.getTextField().getText() != null && app.getTextField().getText().length() > 0) {
String message = MessageUtil.getMessage(Message.LOGGER_PREFIX) + " <" + user.getUsername() + "> " + app.getTextField().getText() + "\n";
try {
output.writeUTF(message);
output.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
} catch (UnknownHostException e) {
System.out.println(e);
System.out.println("Could not connect! Reason: " + e);
} catch (IOException e) {
System.out.println("Could not connect! Reason: " + e);
}
}
ServerConnection
public class ServerConnection implements Runnable {
#SuppressWarnings("unused")
private Socket socket;
private DataInputStream in;
private ClientApplicationUI app;
public ServerConnection(Socket socket, ClientApplicationUI app) throws IOException {
this.socket = socket;
this.app = app;
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}
#Override
public void run() {
while (true) {
String message;
try {
message = in.readUTF();
app.logMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Server
public class Server {
private Socket socket = null;
private ServerSocket server = null;
private ExecutorService pool = Executors.newFixedThreadPool(4);
public Server (int port) {
try {
ApplicationUI app = new ApplicationUI();
app.setVisible(true);
server = new ServerSocket(port);
app.logMessage(MessageUtil.getMessage(Message.LOGGER_PREFIX) + " " + MessageUtil.getMessage(Message.INFO) + " Server started!\n");
app.logMessage(MessageUtil.getMessage(Message.LOGGER_PREFIX) + " " + MessageUtil.getMessage(Message.INFO) + " Waiting for new connections...\n");
while (true) {
socket = server.accept();
ConnectionHandler clientThread = new ConnectionHandler(socket, app);
app.logMessage(MessageUtil.getMessage(Message.LOGGER_PREFIX) + " " + MessageUtil.getMessage(Message.INFO) + " A new client has been accepted!\n");
pool.execute(clientThread);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server(58139);
}
}
ConnectionHandler
public class ConnectionHandler implements Runnable {
private Socket client;
private ApplicationUI app;
private DataInputStream in;
private DataOutputStream out;
public ConnectionHandler(Socket client, ApplicationUI app) throws IOException {
this.client = client;
this.app = app;
in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
}
#Override
public void run() {
try {
app.getButton().addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (app.getTextField().getText() != null && app.getTextField().getText().length() > 0) {
String message = MessageUtil.getMessage(Message.LOGGER_PREFIX) + " <Server> " + app.getTextField().getText() + "\n";
try {
sendMessage(message);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
String message = "";
while (!message.equals("/stop")) {
message = in.readUTF();
app.logMessage(message);
}
} catch (IOException e) {
System.err.println("IO exception in connection handler!");
System.err.println(e.getStackTrace());
} finally {
try {
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void sendMessage(String message) throws IOException {
out.writeUTF(message);
out.flush();
}
}
You need to understand, how sockets work. They are always Client and Server.
There are two ways you could achieve what you want:
First solution:
Send the message which is meant for all clients to the server and let the server distribute the message to all the other clients. The server will need to keep track of the already connected clients, i.e. store their Socket.
Second solution: (which totally is not advisable)
If you want to send a message to a client of a network without haveing the actual server involved, you will need that client to act as a server, or the other way around. This means that every client will actually need to listen to every other client, instead of only the server.
You should definitely go with the first solution!
I wanted to ask how to change following code, which needs USB connection and WIFI to work... (and I don't know why wifi...), to code, which needs only USB cable and NO WIFI!, because I don't want to be dependent on wifi...
Could you please help me? Some changes or additions in code? Thanks.
Code for Android:
private final Runnable connectToServer = new Thread()
{
#Override
public void run()
{
try
{// Get the server address from a dialog box.
String serverAddress = "192.168.0.23";
// Make connection and initialize streams
Socket socket = new Socket(serverAddress, 38300);
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// Consume the initial welcoming messages from the server
for (int i = 0; i < 3; i++) {
System.out.println(in.readLine());
}
solveCube();
} catch (IOException e) {
e.printStackTrace();
}
}
};
private final Runnable initializeConnection = new Thread()
{
#Override
public void run()
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(generateCubeString());
out.println(generateCubeString());
String response ="";
try {
response = in.readLine();
if (response == null || response.equals("")) {
System.exit(0);
}
} catch (IOException ex) {
}
if (response.contains("Error")) {
} else {
solveCubeAnimate(response);
}
System.out.println(response);
final String finalResponse = response;
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(finalResponse);
}
});
}
};
Code for PC
private static class Capitalizer extends Thread {
private Socket socket;
private int clientNumber;
public Capitalizer(Socket socket, int clientNumber) {
this.socket = socket;
this.clientNumber = clientNumber;
log("New connection with client# " + clientNumber + " at " + socket);
}
/**
* Services this thread's client by first sending the
* client a welcome message then repeatedly reading strings
* and sending back the capitalized version of the string.
*/
public void run() {
try {
// Decorate the streams so we can send characters
// and not just bytes. Ensure output is flushed
// after every newline.
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
// Send a welcome message to the client.
out.println("Hello, you are client #" + clientNumber + ".");
out.println("Enter a line with only a period to quit\n");
// Get messages from the client, line by line; return them
// capitalized
while (true) {
String input = in.readLine();
if (input == null || input.equals(".")) {
break;
}
out.println(solveCube(input));
}
} catch (IOException e) {
log("Error handling client# " + clientNumber + ": " + e);
} finally {
try {
socket.close();
} catch (IOException e) {
log("Couldn't close a socket, what's going on?");
}
log("Connection with client# " + clientNumber + " closed");
}
}
/**
* Logs a simple message. In this case we just write the
* message to the server applications standard output.
*/
private void log(String message) {
System.out.println(message);
}
}
private static class Connecter extends Thread {
/**
* Services this thread's client by first sending the
* client a welcome message then repeatedly reading strings
* and sending back the capitalized version of the string.
*/
public void run() {
try {
System.out.println("The capitalization server is running.");
int clientNumber = 0;
ServerSocket listener = new ServerSocket(38300);
try {
while (true) {
new Capitalizer(listener.accept(), clientNumber++).start();
}
} finally {
listener.close();
}
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I made an app client in android device (with ethernet and wireless port) and server application in windows.
Data transfers via Socket programming between devices and when i test it in emulator in PC or run in Ethernet via cable it works correctly, but when i connect server and client with wireless connectivity (via an access point) data sent or received with a delay . this delay may be take over 60 seconds !
i don't know why this problem happend !
This is my sending routin in android :
Server_Port = mDbHelper.GetPortNumber();
//mDbHelper.close();
final String Concatinate_values = firstByte_KindType + Spliter + secoundByte_KindofMove +
Spliter + ValueOfMove + Spliter + valueOfsetting + Spliter + MaxOrMinValue;
//Sent Routin
////‌Connect To server
Thread thread = null;
thread = new Thread(new Runnable() {
#Override
public void run() {
DataOutputStream outputStream = null;
BufferedReader inputStream = null;
Socket socket;
socket = new Socket();
try {
socket.connect(new InetSocketAddress(Server_IP, Server_Port), 10);
}
catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
Thread.currentThread().interrupt();
}
////Make Read Line
try {
outputStream = new DataOutputStream(socket.getOutputStream());
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (IOException e1) {
//Finished Socket
ShutDown(socket);
}
if (outputStream == null) {
//
ShutDown(socket);
Thread.currentThread().interrupt();
return;
}
//Write Message
try {
String message = Concatinate_values + "\n";
outputStream.write(message.getBytes());
outputStream.flush();
ShutDown(socket);
Thread.currentThread().interrupt();
return;
}
catch (IOException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
try {
if (socket != null) {
socket.close();
}
}
catch (IOException e) {
e.printStackTrace();
ShutDown(socket);
Thread.currentThread().interrupt();
return;
}
Thread.currentThread().interrupt();
}
});
thread.start();
My windows server code in c# :
class Program
{
static Socket socketForClient;
static NetworkStream networkStream;
static System.IO.StreamReader streamReader;
static System.IO.StreamWriter streamWriter;
static TcpListener tcpListener;
static int PORT;
static void Main(string[] args)
{
//Console.WriteLine("Enter Port : ");
//PORT = Convert.ToInt32(Console.ReadLine());
PORT = 12500;
Console.WriteLine("\n" + "Your Host Information Is : "+"\n" );
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress ip in localIPs)
{
Console.WriteLine(ip.ToString());
}
while (true)
{
tcpListener = new TcpListener(PORT);
Console.WriteLine("\n >> Server started ... Waiting for Message");
tcpListener.Start();
try
{
socketForClient = tcpListener.AcceptSocket();
}
catch (System.Exception e1)
{
Console.WriteLine("LN: 40");
Console.WriteLine("Message: " + e1.Message);
Console.WriteLine("InnerException: " + e1.InnerException);
Console.WriteLine("Source: " + e1.Source);
Console.ReadLine();
}
if (socketForClient.Connected)
{
Console.WriteLine("Client connected");
try
{
networkStream = new NetworkStream(socketForClient);
}
catch (System.Exception e1)
{
Console.WriteLine("LN: 55");
Console.WriteLine("Message: " + e1.Message);
Console.WriteLine("InnerException: " + e1.InnerException);
Console.WriteLine("Source: " + e1.Source);
Console.ReadLine();
}
//System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(networkStream);
try
{
streamReader = new System.IO.StreamReader(networkStream);
streamWriter = new System.IO.StreamWriter(networkStream);
}
catch (System.Exception e1)
{
Console.WriteLine("LN: 71");
Console.WriteLine("Message: " + e1.Message);
Console.WriteLine("InnerException: " + e1.InnerException);
Console.WriteLine("Source: " + e1.Source);
Console.ReadLine();
}
string theString = "Sending";
// streamWriter.WriteLine(theString);
Console.WriteLine(theString);
//streamWriter.Flush();
long x = 0;
try
{
x++;
theString = streamReader.ReadLine();
if (theString.Trim() == "4-")
{
Console.WriteLine("Sending Report Data : 0-100-0-0");
streamWriter.WriteLine("0-70-0-0");
Console.WriteLine("pocket sent");
streamWriter.Flush();
}
Console.WriteLine(theString + x.ToString());
streamReader.Close();
networkStream.Close();
socketForClient.Close();
tcpListener.Stop();
}
catch (System.Exception e1)
{
streamReader.Close();
networkStream.Close();
socketForClient.Close();
Console.WriteLine("LN: 97");
Console.WriteLine("Message: " + e1.Message);
Console.WriteLine("InnerException: " + e1.InnerException);
Console.WriteLine("Source: " + e1.Source);
Console.ReadLine();
break;
//streamWriter.Close();
}
}
}
streamReader.Close();
networkStream.Close();
socketForClient.Close();
Console.WriteLine("Closed Socket");
Console.ReadLine();
}
}
I wanna write the code to let Client send a string to Server, Server print the string and reply a string, then Client print the string Server reply.
My Server
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = null;
Socket s = null;
try {
ss = new ServerSocket(34000);
s = ss.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
s.getInputStream()));
OutputStreamWriter out = new OutputStreamWriter(s.getOutputStream());
while (true) {
String string = in.readLine();
if (string != null) {
System.out.println("br: " + string);
if (string.equals("end")) {
out.write("to end");
out.flush();
out.close();
System.out.println("end");
// break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
s.close();
ss.close();
}
}
}
My Client:
public class Client {
public static void main(String[] args) {
Socket socket =null;
try {
socket = new Socket("localhost", 34000);
BufferedReader in =new BufferedReader(new InputStreamReader(socket.getInputStream()));
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
String string = "";
string = "end";
out.write(string);
out.flush();
while(true){
String string2 = in.readLine();
if(string2.equals("to end")){
System.out.println("yes sir");
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
System.out.println("closed client");
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
are there some somethings wrong? if i remove the code "while(true) ..." in client class, it's OK.
you should add "\r\n" at the end of the String which write into stream.
example:
client :
string = "end";
out.write(string + "\r\n");
out.flush();
server :
out.write("to end" + "\r\n");
out.flush();
out.close();
System.out.println("end");
// break;
I don't see the server response.
You do a
System.out.println("br: " + string);
but not a
out.write(string);
out.flush();
Appand "\n" to end of the response from server.
outToClient.writeBytes(sb.toString() + "\n");
You are reading lines but you aren't writing lines. Add a newline, or call BufferedReader.newLine().
I am new to java TCP socket. I tried to implement a server and a client. So the server should check input (do something) and send string to client. The client should send string to the server and look for an input string from the server (and do something). Both should loop checking and sending all the time if something new is available.
The client can send data to the server, the server receives it an can display/process this data.
But the data from the server isn't displayed by the client. Can someone tell me why the client isn't receiving the string from the server? Any better ideas to do endless loop? There will be only one client and one server.
while true:
server out------> send String-----> in client
in<----- sent String <------ out
this is the simplified server part:
public class MainActivity extends Activity {
Socket client;
ServerSocket server;
int serverport = 54321;
String inputData = null;
BufferedReader in;
PrintWriter out;
String outputData;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(setupConnection).start();
}
private Runnable setupConnection = new Thread() {
public void run() {
try {
server = new ServerSocket(serverport);
while (true) {
client = server.accept();
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
inputData = in.readLine();
InputStream inStream = new ByteArrayInputStream(inputData.getBytes());
in.close();
if (inputData != null) {
System.out.println(TAG + "-----Incoming Message---- " + inputData);
//this is working String is shown
} }
out.write("nothing to do?");
out.flush();
out.close();
}
} catch (SocketException e) {
Log.v(TAG, "SocketException: " + e);
e.printStackTrace();
} catch (IOException e) {
Log.v(TAG, "IOException: " + e);
e.printStackTrace();
}
}
the simplified client looks like this:
public class testClass {
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = null;
String host = "127.0.0.1";
int port = 54321;
PrintWriter out = null;
BufferedReader in = null;
while (true) {
try {
socket = new Socket(host, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.out.println(TAG + "Error: " + e);
System.err.println("Don't know about host: localhost.");
System.exit(1);
} catch (IOException e) {
System.out.println(TAG + "Error: " + e);
System.err.println("Couldn't get I/O for " + "the connection to: localhost.");
System.exit(1);
}
out.println("Hello, is it me you're looking for...");
out.flush();
String input = in.readLine();
System.out.println("Input: " + input);
in.close();
out.close();
}
}
}
If readLine() returns null,the peer has closed the connection, and you must do likewise. And stop reading.
if you want implement this code in android , you faces many problems:
you can find the solution in this link:
Post JSON in android
in the following code may be fix this problem:
HttpPost post = new HttpPost("http://xxxxxx");
DefaultHttpClient httpClient = new DefaultHttpClient();
post.setEntity(new ByteArrayEntity(json.toString().getBytes()));
HttpResponse response = httpClient.execute(post);
return EntityUtils.toString(response.getEntity());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
System.out.println(">>>>>>>" + e.getMessage());
} catch (ClientProtocolException e) {
e.printStackTrace();
System.out.println(">>>>>>>" + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
System.out.println(">>>>>>>" + e.getMessage());
}