I would like to that when the server gets a message from the client and the message is for example "start", server sends back ips and ports of the rest of clients.
Part of the server:
...
for (i = 0; i < max_clients; i++) {
sd = client_socket[i];
memset(buffer, 0, 10000);
if (FD_ISSET( sd , &readfds)) {
if ((valread = read( sd , buffer, 1024)) == 0) {
getpeername(sd, (struct sockaddr*)&address, (socklen_t*)&addrlen);
printf("Host disconnected , ip %s , port %d \n" ,
inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
close( sd );
client_socket[i] = 0;
}
else {
char cmd[10] = "";
int k;
for(k=0; k<strlen(buffer)-1; k++) {
char tmp[2] = "";
tmp[0] = buffer[k];
strcat(cmd, tmp);
}
if (strcmp(cmd, "start") == 0) {
char clientInfo[1000] = "[ ";
for(j=0; j<max_clients; j++) {
if (client_socket[j] > 0 && client_socket[j] != sd) {
char port[12];
sprintf(port, "%d", clients[j].port);
strcat(clientInfo, "{");
strcat(clientInfo, clients[j].addr);
strcat(clientInfo, " - ");
strcat(clientInfo, port);
strcat(clientInfo, "} ");
}
}
strcat(clientInfo, "]");
send(sd, clientInfo, strlen(clientInfo), 0);
printf("%s\n", clientInfo);
} else {
buffer[valread] = '\0';
for(j=0; j<max_clients; j++) {
int outSock = client_socket[j];
if(outSock != master_socket && outSock != sd) {
send(outSock , buffer , strlen(buffer) , 0 );
}
}
}
}
}
}
...
Part of the client:
public ChatWindowController() {
try {
clientSocket = new Socket("127.0.0.1", 54000);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
thread = new Thread() {
#Override
public void run() {
try {
while(isRunning) {
if (ta_display != null) {
String message = inFromServer.readLine();
System.out.println(message);
ta_display.appendText(message + '\n');
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
};
thread.start();
} catch(Exception e) {
e.printStackTrace();
}
}
...
...
#FXML
void sendMsg(ActionEvent event) {
String message = tf_user_input.getText();
if (username == null || username.equals("") || username.trim().equals("")) {
ta_display.appendText("You can not send a message, set your username!\n");
return;
}
if (message != null && !message.equals("") && !message.trim().equals("")) {
try {
out.println(username + ": " +message);
out.flush();
} catch(Exception e) {
e.printStackTrace();
}
ta_display.appendText(username + ": " + message + "\n");
}
tf_user_input.setText("");
}
#FXML
void sendFile(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(null);
out.println("start");
out.flush();
}
Messages from clients are sent to the server, and the server sends them to other clients, it works.
But when client send message "start" to the server I want to send back ips and ports of the rest of the clients, but it doesn't arrive to the client back, only when one of the other clients writes something, a message with ip and user ports comes.
E.g. "[{127.0.0.1 - 1234} {127.0.0.1}]User: example"
Like the message has been lost and arrived with another. I print the ips and ports to see if everything is alright and it prints corectly.
I'm not getting any errors.
Does anybody know how to send back a message after specific message from client?
Related
I created custom Twitch bot with using of cavariux library. I called this methods in main class.
bot.setOauth_Key("oauth:key_Value");
bot.connect();
bot.joinChannel(channel.toString());
bot.start();
Approximately one of the 5-6 launches of the bot is accompanied by an exception
java.net.SocketException: Connection reset by peer
. The stack trace indicates that the exception starts on this line.
while ((line = this.reader.readLine( )) != null && !stopped)
in TwitchBot class in method start(). I didn't change code of this library except adding utf encoding in method connect(String ip, int port).
this.writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
I've tested my bot on different PCs. On some machines I don't have this issue. On some I got this exception more often.
This is code of method start() in TwitchBot class.
public final void start()
{
if (isRunning()) return;
String line = "";
stopped = false;
try {
while ((line = this.reader.readLine( )) != null && !stopped) {
if (line.toLowerCase( ).startsWith("ping")) {
LOGGER.log(Level.INFO,"> PING");
LOGGER.log(Level.INFO,"< PONG " + line.substring(5));
this.writer.write("PONG " + line.substring(5) + "\r\n");
this.writer.flush();
} else if (line.contains("PRIVMSG"))
{
String str[];
str = line.split("!");
final User msg_user = User.getUser(str[0].substring(1, str[0].length()));
str = line.split(" ");
Channel msg_channel;
msg_channel = Channel.getChannel(str[2], this);
String msg_msg = line.substring((str[0].length() + str[1].length() + str[2].length() + 4), line.length());
LOGGER.log(Level.INFO,"> " + msg_channel + " | " + msg_user + " >> " + msg_msg);
if (msg_msg.startsWith(commandTrigger))
onCommand(msg_user, msg_channel, msg_msg.substring(1));
if (msg_user.toString().equals("jtv") && msg_msg.contains("now hosting")) {
String hoster = msg_msg.split(" ")[0];
onHost(User.getUser(hoster), msg_channel);
}
onMessage(msg_user, msg_channel, msg_msg);
} else if (line.contains(" JOIN ")) {
String[] p = line.split(" ");
String[] pd = line.split("!");
if (p[1].equals("JOIN"))
userJoins(User.getUser(pd[0].substring(1)), Channel.getChannel(p[2], this));
} else if (line.contains(" PART ")) {
String[] p = line.split(" ");
String[] pd = line.split("!");
if (p[1].equals("PART"))
userParts(User.getUser(pd[0].substring(1)), Channel.getChannel(p[2], this));
} else if (line.contains(" WHISPER ")) {
String[] parts = line.split(":");
final User wsp_user = User.getUser(parts[1].split("!")[0]);
String message = parts[2];
onWhisper(wsp_user, message);
} else if (line.startsWith(":tmi.twitch.tv ROOMSTATE")) {
} else if (line.startsWith(":tmi.twitch.tv NOTICE"))
{
String[] parts = line.split(" ");
if (line.contains("This room is now in slow mode. You may send messages every"))
{
LOGGER.log(Level.INFO,"> Chat is now in slow mode. You can send messages every " + parts[15] + " sec(s)!");
} else if (line.contains("subscribers-only mode")) {
if (line.contains("This room is no longer"))
LOGGER.log(Level.INFO,"> The room is no longer Subscribers Only!");
else
LOGGER.log(Level.INFO,"> The room has been set to Subscribers Only!");
} else {
LOGGER.log(Level.INFO,line);
}
} else if (line.startsWith(":jtv MODE "))
{
String[] p = line.split(" ");
if (p[3].equals("+o")) {
LOGGER.log(Level.INFO,"> +o " + p[4]);
} else {
LOGGER.log(Level.INFO,"> -o " + p[4]);
}
} else if (line.toLowerCase().contains("disconnected"))
{
LOGGER.log(Level.INFO, line);
this.connect();
} else
{
LOGGER.log(Level.INFO,"> " + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
This is code of method connect() in TwitchBot class.
public void connect(String ip, int port)
{
if (isRunning()) return;
try{
if (user == null || user == "")
{
LOGGER.log(Level.SEVERE, "Please select a valid Username");
System.exit(1);
return;
}
if (oauth_key == null || oauth_key == "")
{
LOGGER.log(Level.SEVERE,"Please select a valid Oauth_Key");
System.exit(2);
return;
}
#SuppressWarnings("resource")
Socket socket = new Socket(ip, port);
this.writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
this.reader = new BufferedReader(new InputStreamReader(socket.getInputStream(),StandardCharsets.UTF_8));
this.writer.write("PASS " + oauth_key + "\r\n");
this.writer.write("NICK " + user + "\r\n");
this.writer.write("USER " + this.getVersion() + " \r\n");
this.writer.write("CAP REQ :twitch.tv/commands \r\n");
this.writer.write("CAP REQ :twitch.tv/membership \r\n");
this.writer.flush();
String line = "";
while ((line = this.reader.readLine()) != null)
{
if (line.indexOf("004") >= 0) {
LOGGER.log(Level.INFO,"Connected >> " + user + " ~ irc.twitch.tv");
break;
}else {
LOGGER.log(Level.INFO,line);
}
}
} catch (IOException e)
{
e.printStackTrace();
}
}
Thank you for the help
This error means that the peer (i.e. the Twitch server) closes abruptly your connection. See this answer for more details.
I don't know if you can do something to fix that because it can have various external origins (peer crash...). Maybe you can wait and try to reconnect later (note that you might be blacklisted if you connect too often).
I have bidirectional communication between Java and Arduino, but am finding that when sending data from Java to Arduino it takes about 3.5 seconds to show up in the sketch.
Data sent from Arduino to Java has no such latency.
Any idea why this is the case?
Arduino code.
Here's my main loop,
void loop() {
connection.sendData(systemVariables);
connection.receiveData(systemVariables);
world(systemVariables, ctr++);
}
Here's the sender,
void sendData(SystemVariables &sv) {
String msg = String(sv.getReference());
String pstr = String(sv.getPosition(), 2);
msg = msg + "," ;
msg = msg + pstr;
msg = msg + "," ;
msg = msg + sv.getOutput();
Serial.println(msg);
}
Here's the receiver,
float receiveData(SystemVariables &sv) {
String str;
while (Serial.available() > 0) {
str = Serial.readStringUntil('\n');
Serial.print('>');
Serial.println(str);
}
if (str.length() > 0)
sv.setOutput( str.toFloat());
return sv.getOutput();
}
Java
The Java loop has a 25ms delay.
receiver
public synchronized void serialEvent(SerialPortEvent oEvent) {
//System.out.println("ET " + oEvent.getEventType());
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
String inputLine = null;
try {
inputLine = input.readLine();
if (inputLine.length() > 0) {
logger.log(Level.INFO, "{0}", inputLine);
if (!inputLine.startsWith(">")) {
String[] arr = inputLine.split(",");
for (int i = 0; i < arr.length; i++) {
try {
float newf = Float.parseFloat(arr[i]);
try {
if (data.size() <= i) {
data.add(newf);
} else {
data.set(i, newf);
}
} catch (IndexOutOfBoundsException e) {
logger.warning(e.toString());
}
} catch (NumberFormatException e) {
logger.log(Level.WARNING, "{0} <{1}> <{2}>", new Object[]{e.toString(), inputLine, arr[i]});
}
}
}
}
} catch (IOException ex) {
Logger.getLogger(SerialSensorSingleton.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception e) {
logger.warning(e.toString() + " Data received " + inputLine == null ? "null" : "<" + inputLine + ">");
}
}
}
Sender
public void write(String s) throws IOException {
logger.log(Level.INFO, ":{0}", s);
output.write(s.getBytes());
output.flush();
}
I have resolved this now. The problem was that I was trying to implement synchronous communication with asynchronous methodology.
That is, I was using SerialEvent listener, but this is only intended for one way communication. I was trying to use the port to send data back the other way, but it was being blocked by the queue of data that built up for a certain period.
I have changed the method calls to read and writes so that each end sends only one message and than waits for incoming data. In this way each end is synchronised, and it now works like a dream.
I want to find my Server in my network, when I don't know the ip.
So that's the code I have, but it takes really (!) long to test all IPs:
for (int j = 1; j < 255; j++) {
for (int i = 1; i < 255; i++) {
String iIPv4 = "192.168." + j + ".";
try {
Socket socket = new Socket();
SocketAddress address = new InetSocketAddress(iIPv4 + i, 2652 );
socket.connect(address, 5);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String fromServer;
while ((fromServer = in.readLine()) != null) {
if (fromServer.equals("Connected to CC3000")) {
System.out.println("CC3000 found! : " + iIPv4 + i);
return iIPv4 + i;
}
}
} catch (UnknownHostException e) {
} catch (IOException e) {
}
}
}
so, whats a better way to find the server?
regards
I think that multithreading could help you here, since you don't want to be waiting for each connection to either establish or fail.
You can try say hundreds of sockets at once instead. Also checking that IP is reachable might save you some time.
Code below is really a naive and horrible example since there's no thread management at all, but you get the picture I hope. You should get the result much faster.
public static void findLanSocket(final int port, final int timeout) {
List<Thread> pool = new ArrayList<>();
for (int j = 1; j < 255; j++) {
for (int i = 1; i < 255; i++) {
final String iIPv4 = "192.168." + j + "." + i;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("TESTING: " + iIPv4);
try {
// First check if IP is reachable at all.
InetAddress ip = InetAddress.getByName(iIPv4);
if (!ip.isReachable(timeout)) {
return;
}
// Address is reachable -> try connecting to socket.
Socket socket = new Socket();
SocketAddress address = new InetSocketAddress(ip, port);
socket.connect(address, timeout);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String fromServer;
while ((fromServer = in.readLine()) != null) {
if (fromServer.equals("Connected to CC3000")) {
System.out.println("CC3000 found! : " + iIPv4);
}
}
} catch (UnknownHostException e) {
} catch (IOException e) {
}
}
});
pool.add(thread);
thread.start();
}
}
// Wait for threads to die.
for (Thread thread : pool) {
try {
if (thread.isAlive()) {
thread.join();
}
} catch (InterruptedException ex) {
}
}
}
I'm trying to code a UDP client to receive packets from a server that is broadcasting on the local network. The problem is the receive method isn't blocking and waiting for a packet to arrive.
Instead, it's receiving null or empty packets.
I've tried to use .setSoTimeout(0), which supposedly will tell the receive to block until it receives a packet, but it doesn't.
Does anyone know how to fix this?
Here's the code:
while (search == true) {
InetAddress addr = InetAddress.getByName("0.0.0.0");
DatagramSocket sock = new DatagramSocket(1355);
sock.setSoTimeout(0);
byte[] recebe = new byte[1024];
sock.setBroadcast(true);
System.out.println("entrou1");
DatagramPacket packet = new DatagramPacket(recebe, recebe.length);
System.out.println("entrou2");
sock.receive(packet);
String info = new String(packet.getData());
System.out.println("tamanho: " + info.length());
if (info.trim().equals("") == false && info != null) {
System.out.println("entrou aqui");
System.out.println("info recebida:" + info + ":fsadfsfs");
String servs[] = info.split("\n");
list1.clear();
servidores.clear();
for (int i = 0; i < servs.length; i++) {
System.out.println("vec: " + servs[i]);
if (servs[i].trim().equals("")) {
System.out.println("break;");
break;
} else {
String aux = servs[i].substring(0, servs[i].lastIndexOf("->"));
System.out.println("aux: " + aux);
list1.add(aux);
servidores.add(servs[i]);
}
}
}
System.out.println("info:\n" + info);
sock.close();
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException ex) {
Logger.getLogger(AcederPartilhaGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
When i use one jpeg image with this web-server its very slow to show the picture in the browser. But the same picture when i open using Apache web server its super fast.
What am i missing in my code which is so slow to render the jpeg file? Following is the code i am using:
server.java:
package www;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class server extends Thread
{
public server(int listen_port, webserver_starter to_send_message_to)
{
message_to = to_send_message_to;
port = listen_port;
this.start();
}
private void s(String s2)
{
message_to.send_message_to_window(s2);
}
private webserver_starter message_to;
private int port;
public void run()
{
ServerSocket serversocket = null;
s("The httpserver v. 0000000000\n\n");
try {
s("Trying to bind to localhost on port " + Integer.toString(port) + "...");
serversocket = new ServerSocket(port);
}catch (Exception e) {
s("\nFatal Error:" + e.getMessage());
System.exit(0);
return;
}
s("OK!\n");
while (true)
{
s("\nReady, Waiting for requests...\n");
try {
Socket connectionsocket = serversocket.accept();
InetAddress client = connectionsocket.getInetAddress();
s(client.getHostName() + " connected to server.\n");
BufferedReader input =
new BufferedReader(new InputStreamReader(connectionsocket.
getInputStream()));
DataOutputStream output =
new DataOutputStream(connectionsocket.getOutputStream());
http_handler(input, output);
} catch (Exception e) {
s("\nError:" + e.getMessage());
}
}
}
private void http_handler(BufferedReader input, DataOutputStream output)
{
int method = 0; //1 get, 2 head, 0 not supported
String http = new String(); //a bunch of strings to hold
String path = new String(); //the various things, what http v, what path,
String file = new String(); //what file
String user_agent = new String(); //what user_agent
try {
String tmp = input.readLine(); //read from the stream
String tmp2 = new String(tmp);
tmp.toUpperCase(); //convert it to uppercase
if (tmp.startsWith("GET")) { //compare it is it GET
method = 1;
} //if we set it to method 1
if (tmp.startsWith("HEAD")) { //same here is it HEAD
method = 2;
} //set method to 2
if (method == 0) {
try {
output.writeBytes(construct_http_header(501, 0));
output.close();
return;
}
catch (Exception e3) {
s("error:" + e3.getMessage());
}
}
int start = 0;
int end = 0;
for (int a = 0; a < tmp2.length(); a++) {
if (tmp2.charAt(a) == ' ' && start != 0) {
end = a;
break;
}
if (tmp2.charAt(a) == ' ' && start == 0) {
start = a;
}
}
path = tmp2.substring(start + 2, end);
}
catch (Exception e) {
s("errorr" + e.getMessage());
}
s("\nClient requested:" + new File(path).getAbsolutePath() + "\n");
FileInputStream requestedfile = null;
try {
requestedfile = new FileInputStream(path);
}
catch (Exception e) {
try {
output.writeBytes(construct_http_header(404, 0));
output.close();
}
catch (Exception e2) {}
;
s("error" + e.getMessage());
}
try {
int type_is = 0;
if (path.endsWith(".zip"))
{
type_is = 3;
}
if (path.endsWith(".jpg") || path.endsWith(".jpeg"))
{
type_is = 1;
}
if (path.endsWith(".gif"))
{
type_is = 2;
}
output.writeBytes(construct_http_header(200, 5));
if (method == 1)
{
while (true)
{
int b = requestedfile.read();
if (b == -1) {
break; //end of file
}
output.write(b);
}
}
output.close();
requestedfile.close();
}
catch (Exception e) {}
}
private String construct_http_header(int return_code, int file_type)
{
String s = "HTTP/1.0 ";
switch (return_code)
{
case 200:
s = s + "200 OK";
break;
case 400:
s = s + "400 Bad Request";
break;
case 403:
s = s + "403 Forbidden";
break;
case 404:
s = s + "404 Not Found";
break;
case 500:
s = s + "500 Internal Server Error";
break;
case 501:
s = s + "501 Not Implemented";
break;
}
s = s + "\r\n";
s = s + "Connection: close\r\n";
s = s + "Server: SimpleHTTPtutorial v0\r\n";
switch (file_type) {
case 0:
break;
case 1:
s = s + "Content-Type: image/jpeg\r\n";
break;
case 2:
s = s + "Content-Type: image/gif\r\n";
case 3:
s = s + "Content-Type: application/x-zip-compressed\r\n";
default:
//s = s + "Content-Type: text/html\r\n";
s = s + "Content-Type: image/jpeg\r\n";
break;
}
s = s + "\r\n";
return s;
}
}
Well here's the first thing I'd fix:
while (true)
{
int b = requestedfile.read();
if (b == -1) {
break; //end of file
}
output.write(b);
}
You're reading and writing a single byte at a time. That will be painfully slow. Read and write a whole buffer at a time instead:
byte[] buffer = new byte[32 * 1024]; // 32K is a reasonable buffer size
int bytesRead;
while ((bytesRead = requestedfile.read(buffer)) > 0) {
output.write(buffer, 0, bytesRead);
}
There may well be other performance problems in your code - there are certainly a lot of things I'd change about it, including following Java naming conventions everywhere and certainly fixing this:
// You should basically *never* have this code
catch (Exception e){}
... but as you asked about the performance, that's the first bit I've checked for.