I studied the Client-Server chapter of a Java book and I copied the code examples for a easy Client-Server interaction.
The server:
package knowledge;
import java.io.*;
import java.net.*;
public class DateTimeServer {
public static void main(String[] args) {
try {
int port = Integer.parseInt(args[0]);
ServerSocket server = new ServerSocket(port);
System.out.println("DateTimeServer laeuft");
Socket s = server.accept();
new DateTimeProtokoll(s).transact();
} catch (ArrayIndexOutOfBoundsException ae) {
System.out.println("Aufruf: java DateTimeServer <Port-Nr>");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Protocol:
package knowledge;
import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;
public class DateTimeProtokoll {
static SimpleDateFormat time = new SimpleDateFormat(
"´Es ist gerade´H´.´mm´ Uhr.´");
static SimpleDateFormat date = new SimpleDateFormat(
"´Heute ist´EEEE´, der ´dd.MM.yy´");
Socket s;
BufferedReader vomClient;
PrintWriter zumClient;
public DateTimeProtokoll(Socket s) {
try {
this.s = s;
vomClient = new BufferedReader(new InputStreamReader(
s.getInputStream()));
zumClient = new PrintWriter(s.getOutputStream(), true);
} catch (IOException e) {
System.out.println("IO-Error");
e.printStackTrace();
}
}
public void transact() {
System.out.println("Protokoll gestartet");
try {
zumClient.println("Geben Sie DATE oder TIME ein");
String wunsch = vomClient.readLine();
Date jetzt = new Date();
if (wunsch.equalsIgnoreCase("date"))
zumClient.print(date.format(jetzt));
else if (wunsch.equalsIgnoreCase("time"))
zumClient.println(time.format(jetzt));
else
zumClient.println(wunsch + "ist als Kommando unzulaessig!");
s.close();
} catch (IOException e) {
System.out.println("IO-Error");
}
System.out.println("Protokoll beendet");
}
}
The Client:
package knowledge;
import java.net.*;
import java.io.*;
public class DateTimeClient {
public static void main(String[] args) {
String hostName="";
int port;
Socket c=null;
try{
hostName=args[0];
port= Integer.parseInt(args[1]);
c=new Socket(hostName,port);
BufferedReader vomServer=new BufferedReader(
new InputStreamReader(c.getInputStream()));
PrintWriter zumServer=new PrintWriter(c.getOutputStream(),true);
BufferedReader vonTastatur=new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Server "+ hostName+":"+port+ "sagt:");
String text=vomServer.readLine();
System.out.println(text);
text=vonTastatur.readLine();
zumServer.println(text);
text=vomServer.readLine();
System.out.println(text);
c.close();
}
catch(ArrayIndexOutOfBoundsException ae){
System.out.println("Aufruf:");
System.out.println("java DateTimeClient <HostName><PortNr>");
}
catch(UnknownHostException ue){
System.out.println("Kein DNS-Eintrag fuer: "+hostName);
}
catch(IOException e){
System.out.println("IO-Error");
}
}
}
Here are some notes of my approach and my beliefs. Please disagree on wrong statements stated below:
1)I believe it is no problem to run Client as well as Server on the same (my) computer.
2)I use Eclipse, so I run Eclipse two times in two different workspaces.
3)My input for server program is (run configuration->arguments): 2222
4)My input for the client program is: 2223 my_ip
(my_ip is for example 127.0.0.1 I choosed to write my_ip instead because I am not sure if it is dangerous to reaveal my ip in public)
4b) also: "2223" "my_ip"
4c) and: {"2223","my_ip"}
5) also 2222 my_ip
(although the figure in my book suggests that the port numbers of client and server should be different, but you never know)
Also I get this very often this error message:
Address already in use sounds like client and server port numbers should be different. But I dont know and thats why I ask. Thank you for your help
(The page did not like my code so I took screenshots :/)
I replaced the images with code. Sorry for the inconvenience.
Restarting first the server with input 2222 and then the client with input 127.0.0.1 2222. After a while the client posts "IO-Error". Its the exception from the clien class (not from protocol class) right? Why is the exception triggered? Is the code working for someone? Thank you
1) Correct. Client and server can be on the same computer, no problem there.
2) Not required, but ok.
3) This will make the server listen on port 2222
4) 127.0.0.1 is just another way of saying "this computer". It is the same as "localhost". Your actual ip is irrelevant to the question anyway, 127.0.0.1 will suffice.
5) Your server is asking on which port to listen (the SOURCE port), your client is asking to which port to connect to (the TARGET port of the client). Of course that should be the SAME port, otherwise the client will try to send a message to port X while the server will listen on port Y.
Imagine the ip as a house address, for example "Mainstreet 12, MyCity". The port would be the appartment number then. Your server occupies appartment 2222, so of course the client needs to try to connect to appartment 2222, otherwise it will not reach any server.
The error is most likely just because you don't actually stop your old server program. Stop it (big red button in eclipse), otherwise it will "occupy" the given port (which will prevent any other program from listing at that port, thus you cannot have two servers running which are both listening on the same port). If we reuse my crude analogy: An appartment cannot contain two servers at the same time, so if one is already in appartment 2222, a second one trying to live there will fail.
I don't know exactly why, but usually server binds host as 127.0.0.1 or localhost or your IP like 192.168.1.100 but if one of that are not listed, than it might be failed to call. See more with netstat.exe on Windows.
The "Address already in use" exception is only because the last Java session still running, could not terminate for some reason, and if you use IDE like Eclipse, it will often happen. :)
Make sure that all java thread is terminated (with task manager in Windows). Note that Eclipse is a Java thread too! You would better run the server in console mode..
In real world, native sockets are rarely used, because there some higher level protocol and technology like HTTP, SOAP, WebService, microService, SOA etc. If native socket is not necessary, for example you communicate with microcontroller, you should use these technologies, because these are more robust and others can easily communicate with your interface.
Related
I recently tried creating a socket server which can connect to multiple clients... I was too lazy to write a separate program for the client so I'm just using telnet.
The first time I connect(using telnet), it works fine... but the second telnet connection just hangs and the cmd screen goes blank...
Even the first connection gets hanged after sending a string.
Any help is appreciated
Here's the code:
Chatserver.java
I would really appreciate I if someone would correct the mistakes in the code and post it
You could have a look at it if you want but it might be easier if you just clicked the hyperlink and viewed the image:
package chatserver;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
class Chat extends Thread {
#Override
public void run() {
Chat server = new Chat();
try {
server.SERVER();
} catch (Exception ex) {
Logger.getLogger(Chat.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void SERVER() throws Exception {
ServerSocket SRVSOCK = new ServerSocket(8068);
Socket SOCK = SRVSOCK.accept();
InputStreamReader IR = new InputStreamReader(SOCK.getInputStream());
BufferedReader BR = new BufferedReader(IR);
PrintStream PS = new PrintStream(SOCK.getOutputStream());
PS.println("What is your name: ");
String name = BR.readLine();
String Message = BR.readLine();
PS.println(name + " : " + Message);
}
}
public class ChatServer {
public static void main(String[] args) {
Chat c1 = new Chat();
Chat c2 = new Chat();
while (true) {
c1.start();
c2.start();
}
}
}
Guys,
Today I typed up the same code in python as I am much more familiar with it than I am with Java
I have succeeded in connecting to multiple clients but am unable to see outputs from chat() yet...
I would like to know what mistake I made in this code below and would be very grateful if someone helps me transcribe it to Java:
#!/usr/bin/env python3
import socket
import threading
import time
clients = []
addr = []
HOST = '127.0.0.1'
PORT = 8068
client_no = 0
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
print('Socket bind complete')
def connect(clnt_no):
while True:
s.listen(1)
print('searching for clients')
clnt, adr = s.accept()
clients.append(clnt)
addr.append(adr)
print('connected to: ',addr[clnt_no])
# print(len(clients))
clnt_no += 1
client_no = clnt_no
def chat():
while True:
for x in range(0, client_no):
data = clients[x] = recv(1204)
if data:
for y in range(0, client_no):
clients[y].send('from client ', x, ' ', data)
else:
print('no data recieved from any client')
def Main():
conn = threading.Thread(target=connect, args=[0])
cht = threading.Thread(target=chat)
# while True:
conn.start()
cht.start()
if(__name__ == '__main__'):
Main()
Thanks in advance
Two problems:
First, every instance of Chat is listening on port 8068. You can only have one ServerSocket listening on a particular port, though it is free to accept() multiple connections. If you paid attention to the exceptions you’re getting instead of ignoring them, you would see an exception informing you of this.
Second, since the start() method of Thread returns immediately rather than waiting for the thread to finish, your while loop is creating hundreds, if not thousands, of threads. The only reason your system isn’t overwhelmed by them is because, as I mentioned above, all but the very first instance are immediately failing to bind their ServerSockets, so they return fairly quickly.
In summary, you need to create one server, with one ServerSocket. You will need to call accept() inside a loop, but you must not create more than one ServerSocket.
I am tring to ping IP addresses from 192.168.1.1 to 192.168.1.254. First I was using I InetAddress class but it was bugged and some IPs where not reachable even if they are. After that I tried this method and it worked very well for single ping IP but when I put it inside for-loop all pinged IPs where reachable... Can you guys tell me what's wrong here?
CODE:
public class Main {
public static void main(String[] args) {
String ip="192.168.1.";
try
{
for(int i=0;i<=254;i++){
String ip2=ip+i;
boolean reachable = (java.lang.Runtime.getRuntime().exec("ping -n 1 "+ip2).waitFor()==0);
if(reachable){
System.out.println("IP is reachable:: "+ip2);
}
else{
System.out.println("IP is not reachable: "+ip2);
}
}
}catch(Exception e)
{
e.printStackTrace();
}
}
}
EDIT 1:
I used built in Java function to preform pinging but it's not working (again)
here is code that I used
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Test {
public static void main(String[] args) throws UnknownHostException, IOException {
String ip = "192.168.1.243";
InetAddress inet = InetAddress.getByName(ip);
System.out.println("Sending Ping Request to " + ip);
if (inet.isReachable(5000)){
System.out.println(ip+" is reachable");
}
else{
System.out.println(ip+" is not reachable");
}
}
}
OUTPUT IS:
Sending Ping Request to 192.168.1.243
192.168.1.243 is not reachable
Also here is ping result when I do pinging from Windows 7 built in Ping function (cmd)
Use isReachable() instead.
InetAddress.getByName(address).isReachable(timeout);
Why it does not work:
You are using the exit status of the ping process, not the actual result of the ping itself. It will just tell you whether or not the process exited normally or not. A failed ping does not cause the process to exit abnormally, and thus an exit code of 0 (zero) is always returned.
What you could try instead:
Get the output stream of the process, which will tell you what the output is. Then try to interpret/parse this however you would like:
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Process.html#getOutputStream%28%29
(Although this also doesn't feel perfect for me, it is a much better choice than using the exit code)
Dear sir The issue why you program cannot ping systems over the loop is, the execution of the loop is faster compared to the replies from the systems.That is why some of them replies Unreachable, in order to solve such problem you are supposed to use a thread and introduce a little delay on each ping by using Thread.sleep() method.I think this will work Thank you
Thank everyone to see my problem.
I'd like to explain my problem on Socket with java.
Using socket ,one for server to waiting for connection from client, the other for client to connect with server. THERE ARE TWO PROBLEM~~
(1)
+++After they all connect with each other, the two side can exchange messages to each other. I'have already finished the two Application code with server and client with each own main THREAD,but I can't let them communicate with each other. I use windows command to run this two file .class. I run server first ,and then I run client. They can't communicate with each other. I Want to know whether this is a problem about congestion.If I establish a another thread ,this problem could be solved??
(2) I attempt to run this two application on two eclipse,in other words each eclipse run one application. Why this problem can be solved??
(3)HERE is my code for client:
import java.util.*;
import java.io.*;
import java.net.*;
public class CC {
public static void main(String args[]){
Socket client=null;
DataInputStream in=null;
DataOutputStream out=null;
try{
client=new Socket("127.0.0.1",2060);
in=new DataInputStream(client.getInputStream());
out=new DataOutputStream(client.getOutputStream());
System.out.println("You are a client,you send message to server");
Scanner cin=new Scanner(System.in);
while(true){
String send=null,receive=null;
System.out.println("Please input Client message sending to server!");
send=cin.nextLine();
out.writeUTF(send);
receive=in.readUTF();
System.out.println("Message from Server is:"+receive);
Thread.sleep(500);
}
}
catch(Exception e){
System.out.println("break!"+e);
}
}
}
Here is my code for server
import java.util.*;
import java.io.*;
import java.net.*;
public class SS {
public static void main(String args[]){
ServerSocket socketServer=null;
DataInputStream in=null;
DataOutputStream out=null;
Socket server;
try{
socketServer=new ServerSocket(2060);
}
catch(Exception e1){
System.out.println("can't estblish socketServer "+e1);
}
try{
Scanner cin=new Scanner(System.in);
System.out.println("you are server ,please send message to client");
server=socketServer.accept();
in=new DataInputStream(server.getInputStream());
out=new DataOutputStream(server.getOutputStream());
while(true){
String send=null,receive=null;
receive=in.readUTF();
System.out.println("get message from client is "+receive);
System.out.println("send message from client");
send=cin.nextLine();
out.writeUTF(send);
}
}
catch(Exception e){
System.out.println("break! "+e);
}
}
}
The server and client code deadlocks.
In the client code you have written send=cin.nextLine();, which blocks until more input is available. In the server code you have written receive=in.readUTF(); which too blocks until input is available.
That is, immediately after a connection is established, both the server and the client expects the other to send something which results in a deadlock and both of them wait indefinitely.
You have to make sure that either the server or the client first sends some output before waiting to accept input.
thank you,I have solve this problem under my friends.Because I have run this application before,the port has been occupied.Then I run this application for the second time,this result these two application can not transfer message. These two Application is totally right.
I was given this sample code from college today and it worked fine inside the college but when I run it (using Eclipse) on my home machine I get permission denied. The machine in college is Windows (7) and my computer at home is Linux (Ubuntu).
Why am I getting the following error?
Error in I/O
Permission denied
I'm using port 338.
Copy of the code :
import java.io.*;
import java.net.*;
import java.util.*;
public class Server
{
public static void main(String[] args)
{
try
{
// First create the input from the keyboard
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Server Program");
// Get the port to listen on
System.out.print("Enter port number to listen on: ");
String port_string = input.readLine();
// The port number needs to be an int, so convert the String to an int
int port = Integer.parseInt(port_string);
// Create a ServerSocket to listen on this address
ServerSocket server = new ServerSocket(port);
// Accept an incoming client connection on the server socket
Socket sock = server.accept();
// Create the output stream to the client
DataOutputStream network = new DataOutputStream(sock.getOutputStream());
// Send message
network.writeUTF("Welcome " + sock.getInetAddress().getHostName() + ". We are " + new Date() + "\n");
// Close sockets. This will cause the client to exit
sock.close();
server.close();
}
catch (IOException ioe)
{
System.err.println("Error in I/O");
System.err.println(ioe.getMessage());
System.exit(-1);
}
}
}
Ports under 1024 are on most modern OS's (Ubuntu included) privileged, and require you to run the program as administrator/root or with elevated privileges.
Try a higher port for testing at home and you should be ok.
You say your home machine is running Ubuntu.
On Ubuntu (and other Unix-like operating systems) normal users are not allowed to listen on ports less than port 1024.
Try running it with a port number >= 1024.
I attempted to create a PHP script which determines if the server (the computer which hosts the java program listed below) is running or not, If it is, the php funciton should return true, if not it returns false.
Here is the server:
package darestium.minecraft.server;
import java.io.BufferedReader;
import java.net.*;
import java.io.*;
public class Server {
private static ServerSocket socket;
private static Socket connection;
private static String command = new String();
private static String responseStr = new String();;
private static int port = 4343;
public static void main(String args[]) {
System.out.println("Signal Server is running.");
try {
socket = new ServerSocket(port);
while (true) {
connection = socket.accept();
InputStreamReader inputStream = new InputStreamReader(connection.getInputStream());
DataOutputStream response = new DataOutputStream(connection.getOutputStream());
BufferedReader input = new BufferedReader(inputStream);
command = input.readLine();
response.writeBytes(responseStr);
response.flush();
//response.close();
System.out.println("Running");
}
} catch (IOException e) {
System.out.println("Fail!: " + e.toString());
}
System.out.println("Closing...");
}
}
And here is the client:
<?
function isRunning() {
$address = 'darestium.dyndns-free.com';
$port = 4343;
$socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
$message = 'loolololol';
try {
socket_connect($socket, $address, $port);
$status = socket_sendto($socket, $message, strlen($message), MSG_EOF, $address, $port);
if ($status != false) {
return true;
}
return false;
} catch (Exception $e) {
return false;
}
}
?>
The following are the error messages that show up on the php page that echos out the result of the function like so:
include('server.php');
echo isRunning();
Then the error messages:
Warning: socket_connect() [function.socket-connect]: unable to connect [0]: No connection could be made because the target machine actively refused it. in C:\Users\darestium\Documents\Portables\xampp\htdocs\darestium\minecraftserver.php on line 9
Notice: Use of undefined constant MSG_EOF - assumed 'MSG_EOF' in C:\Users\darestium\Documents\Portables\xampp\htdocs\darestium\minecraftserver.php on line 11
Warning: socket_sendto() expects parameter 4 to be long, string given in C:\Users\darestium\Documents\Portables\xampp\htdocs\darestium\minecraftserver.php on line 11
I was wondering how I could fix this issue. Also, I would like to be able to send messages to the server, any ideas how I could do this? I am basing this off Simple Java TCP Server and PHP Client Problems
Note: that I am very new to Sockets, and Server/Client communication.
Edit:
#VideanuAdrian OK, just port forwarded the port 4343 and it no longer shows up with the first error, but the function always seems to return false, and the last two errors still show.
You should not close the DataOutputStream object in your server.
Just comment the line response.close(); in your server and the program should work.
When running a Client/Server you need to know if the user that runs the app has access to the port. Ports to 1024 are reserved by the system know apps/services. That´s point 1.
Point 2: One of the best ways is to run the server inside a connection-thread approach. Running in this way, when a new client request arrives, the server can delegate the request handle to the connection thread.
Point 3: The message is related to the protocol. If you are using a built protocol like HTTP or FTP, you must use the protocol rules. If not, you could built your own rules for the message request/response.
I recomend you to read the Java Networking Tutorial before continue. Run all Java examples. Later, you could mix with PHP. The more information about sockets and protocols you have, the better your programm will be.
http://docs.oracle.com/javase/tutorial/networking/
Hope this can help you.