I have 3 clients connected through server using sockets. Can any one help me in understanding the concept of how can i send the message to client#1 specifically without sending that message to client 2 or client 3 or how can i send the message to client 2 without sending that message to client 1 and client 3.Sorry for my bad English.
To Send a message to a client you need to get the output stream of the socket so that you could write data to that stream for example you could do something like :-
public Boolean writeMessage(String Command)
{
try
{
byte[] message = Command.getBytes(Charset.forName("UTF-8")); // convert String to bytes
DataOutputStream outStream = new DataOutputStream(socket.getOutputStream());
outStream.writeInt(message.length); // write length of the message
outStream.write(message); // write the bytes
return true;
}
catch (IOException e)
{
}
return false;
}
To read the message on the other end get the sockets inputStream and read data from it as follows :-
public String readMessage()
{
try
{
DataInputStream dIn = new DataInputStream(socket.getInputStream());
int length = dIn.readInt(); // read length of incoming message
if (length > 0)
{
byte[] message = new byte[length];
dIn.readFully(message, 0, message.length); // read the message
return new String(message, Charset.forName("UTF-8"));
}
}
catch (IOException e)
{
}
return "";
}
the socket that you write to must be the client that you need to send the message to, moreover the client must be ready to read that message at that time, here is a basic Client server program Connect multiple clients to one server
Related
I have written below code to find out if remote socket is SSL/TLS.
I am sending below message with content type BEEP+XML.
in the response I got response byte "128 3 0 0 1 -1 -1 ".
Here, TLS/SSL message type is 128 but I can't find out what message type 128 stands for.
I found below link that lists out possible message type IDs but cannot find 128 in it.
http://blogs.msdn.com/b/kaushal/archive/2012/10/06/ssl-tls-alert-protocol-amp-the-alert-codes.aspx
can anyone share their knowledge on this matter.
I am trying to connect to Webseal Reverse proxy through this code.
byte[] TEST_MESSAGE = null;
StringBuffer buffer = new StringBuffer();
buffer.append("RPY 0 0 . 0 110\r\n");
buffer.append("Content-Type: application/beep+xml\r\n");
buffer.append("\r\n");
buffer.append("<greeting>");
buffer.append(" <profile uri='http://iana.org/beep/TLS' />\r\n");
buffer.append("</greeting>\r\n");
buffer.append("END");
byte[] bytes = null;
try {
bytes = buffer.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException ex) {
// impossible; UTF-8 always supported
}
TEST_MESSAGE = bytes;
Socket socket = null;
try {
// connect to the server
socket = new Socket("localhost", 443);
} catch (ConnectException e) {
// Any connect exception here is most likely because the port is
// not open at all...
}
try {
// send a message to the server
OutputStream output = socket.getOutputStream();
output.write(TEST_MESSAGE);
// Read the server's response. Since we sent a clear message,
// an SSL server should return an error message in the format
// described by the TLS protocol specification.
InputStream input = socket.getInputStream();
I'm trying to write a program which acts as a server that will read bytes from a client that is written in PHP - sends request via socket (which i cannot recode due to policy) Here is the server code:
The server runs in: Red Hat Enterprise Linux Server release 6.2 (Santiago)
public void run() {
try {
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(0);
while(!isInterrupted) {
try {
Socket server = serverSocket.accept();
LOG.info("Request received from : " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
// DataInputStream in = new DataInputStream(
// new BufferedInputStream(server.getInputStream(), 10000));
byte[] bytes = new byte[10000];
int byteDupLength = in.read(t_bytes);
// in.readFully(bytes); // I tried this but to no avail
// int byteDupLength = bytes.length;
LOG.info(byteDupLength);
byte[] byteDup = new byte[byteDupLength];
System.arraycopy(bytes, 4, byteDup, 0, byteDupLength);
// FOR INFORMATION ONLY
/*for (byte b : byteDup){
LOG.info(b);
}*/
ByteBuffer buffer = ByteBuffer.wrap(byteDup);
LOG.info(buffer);
forwardRequest(byteDup);
server.close();
}
catch(SocketTimeoutException s) {
LOG.error("Socket timed out!", s);
break;
}
catch(IOException e)
{
LOG.error("IOException:", e);
break;
}
}
}
catch (IOException ex) {
LOG.error("Server socket is null", ex);
}
LOG.fatal("ReceiverEngine interrupted!");
}
I encountered a problem when the client sends request consisting of 4948 bytes. The only bytes the server can read is 2090.
Another thing that seems a mystery to me is that, when I run the server via Netbeans in my local (which is a Windows 7 Pro), it works as expected. I dont know what is wrong. Please help.. :)
Thanks!
TCP is a byte stream protocol.
The read() method isn't guaranteed to fill the buffer.
Therefore if you don't receive the expected number of bytes in a single read, you have to loop until you do receive them.
readFully() would have worked if the buffer size agreed with the size of what was sent. In your case you specified a buffer of 10,000 bytes, which weren't sent, so it would have blocked waiting for the other 10000-4948 bytes.
I wrote code can send a message to server. Problem is if I capture communication in Wireshark my string message sent from my application looks like this:
hello - 1 packet
If I check the same message sent from Telnet cmd terminal message looks like this:
h - 1 packet
e - 1 packet
l - 1 packet
l - 1 packet
o - 1 packet
So finally it sent entire string by character. Server can read the message from cmd Telnet terminal and reply but can't read the message sent from my application. Is there some way how can I send string like this? I'm not programming server. I'm programming only client side so it's important server has to able read the message correctly. Thanks a lot!
PrintWriter out;
BufferedReader in;
public void run() {
// TODO Auto-generated method stub
try {
InetAddress serverAddr = InetAddress.getByName(hostname);
// create a socket to make the connection with the server
socket = new Socket(serverAddr, port);
Log.i("Terminal", "Socket connecting");
try {
// send the message to the server
out = new PrintWriter(
new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
Log.i("Terminal", "Connected.");
// receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
}catch...
}catch...
}
//send code
public void sendMessage(String message) {
if (out != null && !out.checkError()) {
out.println(message);
out.flush();
Log.i("Terminal", "Message sent.");
}
}
Why not just send each character separately?
Something like this:
public void sendMessage(String message) {
for (String ch : message.split(""))
sendPacket(ch);
sendPacket("\r\n");
}
public void sendPacket(String payload) {
if (out != null && !out.checkError()) {
out.print(payload);
out.flush();
Log.i("Terminal", "Message sent.");
}
}
You said everything was working fine, but if you do run in to issues with packet coalescing in the future you can disable the Nagle algorithm by adding this line:
socket.setTcpNoDelay(true);
right after this one:
socket = new Socket(serverAddr, port);
Okay this is a revised question from earlier today, I have included code to help explain the problem. I am sending two messages from the client to the server. The server then picks the messages up and processes them. The server finally attempts to send a message back to the client(please note in the server code "testmessage"), it is here I am having problems. Either I am not recieving the message at the client side or sending it incorrectly from the server side.
public class ClientConnection {
String address, language, message;
int portNumber;
Socket clientSocket = null;
public ClientConnection(String lan, String mes, String add, int pn) throws IOException{
address = add;
portNumber = pn;
language = lan;
message = mes;
}
public String createAndSend() throws IOException{
// Create and connect the socket
Socket clientSocket = null;
clientSocket = new Socket(address, portNumber);
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Send first message - Message is being correctly received
pw.write(language+"\n");
pw.flush();
// Send off the data
// Send the second message - Message is being correctly received
pw.write(message);
pw.flush();
pw.close();
// Send off the data
// NOTE: Either I am not receiving the message correctly or I am not sending it from the server properly.
String translatedMessage = br.readLine();
br.close();
//Log.d("application_name",translatedMessage); Trying to check the contents begin returned from the server.
return translatedMessage;
}
Server Code:
public class ServerConnection {
public static void main(String[] args) throws Exception {
// Delete - Using while loop to keep connection open permanently.
boolean status = false;
while( !status){
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
// Delete - Working as of here, connection is established and program runs awaiting connection on 4444
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String language = br.readLine();
String message = br.readLine();
// Test - Works
System.out.println(language);
// Test - Works
System.out.println(message);
// Delete - Working as of here, both messages are passed and applied. Messages are received as sent from client.
TranslateMessage tm = new TranslateMessage();
String translatedMessage = tm.translateMessage(language, message);
// NOTE: This seems to be where I am going wrong, either I am not sending the message correctly or I am not receiving it correctly..
// PrintWriter writer = new PrintWriter(new BufferedOutputStream(clientSocket.getOutputStream()));
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
// Send translation back
System.out.println(translatedMessage);
// pw.write(translatedMessage+"\n");
pw.write("Return test"); // Test message!
pw.flush();
// Send off the data
pw.close();
br.close();
clientSocket.close();
serverSocket.close();
}
}
}
The code is a bit of a mess and I can see a few duplicates, I have commented where I feel the problems occour.
Thanks for any help!
You are using BufferedReader.readLine() to read the response from the server, but in the test case you are sending a string that is not terminated with a \n or \r\n, so it will not get the line as far as I can tell from the docs...
public String readLine()
throws IOException
Read a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
An additional suggestion...
When writing request response protocols like this I would not rely on line endings to terminate the requests or responses. Typically I would use either a fully formatted JSON string, or my preference is for a binary protocol where all requests and response are prepended with a binary count (usually 4 bytes bigendian/network byte order). Then the client and server reads the 4 bytes then reads the number of bytes that follow. This handles the packet fragmentation that typically happens over network connections, also it helps avoid DOS attacks by malicious users sending long strings that never terminate.
In Java you can use ByteBuffer.order() to handle bigendian numbers.
This question already has answers here:
Java socket/serialization, object won't update
(2 answers)
Closed 7 years ago.
I'm creating a standard multi-client/server program in Java. The server accepts connections and spawns a new thread to handle each one. The client also spawns a thread to wait for messages from the server. The client and server communicate by passing Message objects through ObjectInputStream and ObjectOutputStreams.
The initial handshake works fine. When the client starts, it opens a socket connection to the server. The server accepts the socket, sends a Message to the client that the connection was successful. Then the client sends its username back, and both client and server start waiting for messages.
Then I send some text from my client which creates a chat message, and sends it successfully to the server. The server receives this message, and attempts to send it out to all connected clients, which it does (there's only one). The problem is that this message never gets back to the client.
// This is Message.send
public void send(ObjectOutputStream stream) throws IOException{
stream.writeObject(this);
}
// ClientThread.run
public void run(){
try {
out = client.getOutputStream();
out.flush();
ObjectInputStream in = client.getInputStream();
Message msg = null;
int len;
byte[] bytes = null;
int i = 0;
// Continuously read new Messages from the server
while(true){
msg = (Message)in.readObject();
processInput(msg);
}
} catch (Exception e) {
Util.showError(e.getMessage(), "Connection Error");
}
System.out.println("Client exited");
}
// ServerThread.run
public void run() {
try {
out = new ObjectOutputStream(client.getOutputStream());
ObjectInputStream in = new ObjectInputStream(client.getInputStream());
Message msg = null;
while(client.isConnected()){
msg = (Message)in.readObject();
processInput(msg);
}
in.close();
client.close();
} catch (Exception e) {
server.addMessage(e.getMessage());
}
}
I don't see any calls to flush(), without which the data may never make it from point a to point b.
I'd recommend using the ObjectOutputStream atop a ByteArrayOutputStream, and pushing the resulting byte array across the wire, and then reversing the process on the other end.