I have written a program on Socket Programming, and I created a client and a server. Codes for both are as follows:
CLIENT:
import java.net.*;
import java.io.*;
public class GreetingClient
{
public static void main(String [] args)
{
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try
{
System.out.println("Connecting to " + serverName
+ " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out =
new DataOutputStream(outToServer);
out.writeUTF("Hello from "
+ client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
SERVER:
import java.net.*;
import java.io.*;
public class GreetingServer extends Thread
{
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run()
{
while(true)
{
try
{
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to "
+ server.getRemoteSocketAddress());
DataInputStream in =
new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out =
new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to "
+ server.getLocalSocketAddress() + "\nGoodbye!");
server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
int port = Integer.parseInt(args[0]);
try
{
Thread t = new GreetingServer(port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
Now, I am unable to run the program in Eclipse, can anyone help me, how to do this ?
Go to RunConfigurations.. and click on the Class Name(as here 'GreetingClient') under the java application in the left pane of RunConfiguration window
on the right side you will get many tab like Main,Arguments,jre,ClassPath etc so now click on the 'Arguments'
below this tag you will get textbox with label Program arguments:
here in this textbox you need to pass your command line argument
for multiple values give single space between the argument values then click on the Apply button
like in above case you need to pass commandline argument twice.
so first you configure for the GreetingServer and then for the GreetingClient and then apply and run one by one
click on the GreetingServer.java and then right click on mouse and select Run As-->Run Configuration.. then go to Java Application and click
GreetingServer -->Argument--> 6000 -->apply and -->run
output like this
Waiting for client on port 6000...
now click on the GreetingClient.java and then right click on mouse and select Run As-->Run Configuration.. then go to Java Application and click
GreetingClient -->Argument--> 127.0.0.1 6000 -->apply and -->run
then you will get your application running and
output like this
Connecting to 127.0.0.1 on port 6000
Just connected to /127.0.0.1:6000
Server says Thank you for connecting to /127.0.0.1:6000
Goodbye!
Any port you can send it your wise just keep in mind port no. should be free
for the eclipse argument passing you can go through this link
Actually, you need to run the programs individually in the
Eclipse-IDE. The output will be indented one on another in next tab on
the output area.
I don't have info about Eclipse.
In Netbeans,you need to run the Client.java file separately. Then,move
to Server.java file and run it separately. You'll see at the bottom
that two windows---one running Client.java and the other running
Server.java will be running independently. Now,send message from
client to server and vice-versa.
EDIT FOR YOUR COMMAND LINE PARAMETER SETTING IN ECLIPSE IDE :-
Go to Project--> Run --> Run Configurations --> Arguments.!
Pass the arguments as
args[0]=127.0.0.1 //local-host
args1=3000 //say 3000,you can give any port no. but take care that it should exist!
Try running the Client program first and then run the server program in Netbeans, the program will run with no problem...
/*Server*/
import java.net.*;
import java.io.*;
public class MyServer
{
public static void main(String args[])throws Exception
{
ServerSocket ss=new ServerSocket(8100);
Socket s=ss.accept();
DataInputStream din=new DataInputStream(s.getInputStream());
DataOutputStream dout=new DataOutputStream(s.getOutputStream());
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String str="",str2="";
while(!str.equals("stop"))
{
str=din.readUTF();
System.out.println("clint Says"+str);
str2=br.readLine();
dout.writeUTF(str2);
dout.flush();
}
din.close();
s.close();
ss.close();
}
}
Related
I am new to working with sockets, and I am working on this project where a connection between my android flutter app and a java server is needed, to do this I am trying socket programming.
The server code is fairly simple, I create a new thread for every client connected and I give them a bunch of URLs, later on, this should be replaced by a query result. here is the java code:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class CrawlitServer {
// The port number on which the server will listen for incoming connections.
public static final int PORT = 6666;
//main method
public static void main(String[] args) {
System.out.println("The server started .. ");
// Create a new server socket
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(PORT);
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
// Listen for incoming connections and create a new thread for each one
while (true) {
try {
new CrawlitServerThread(serverSocket.accept()).start();
}
catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
public static class CrawlitServerThread extends Thread {
private final Socket socket;
public CrawlitServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
List<String> list = new ArrayList<>();
//assign a value to list
list.add("http://www.google.com");
list.add("http://www.yahoo.com");
list.add("http://www.bing.com");
list.add("http://www.facebook.com");
list.add("http://www.twitter.com");
list.add("http://www.linkedin.com");
list.add("http://www.youtube.com");
list.add("http://www.wikipedia.com");
list.add("http://www.amazon.com");
list.add("http://www.ebay.com");
list.add("http://stackoverflow.com");
list.add("http://github.com");
list.add("http://quora.com");
list.add("http://reddit.com");
list.add("http://wikipedia.org");
try {
// Get the input stream from the socket
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
Scanner scanner = new Scanner(inputStream);
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
PrintWriter writer = new PrintWriter(outputStream, true);
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println("Received Message from client: " + line);
writer.println(list + "\n");
}
}
catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
}
Now I run this server and connect to it using sockets in Flutter, I give it the IP address I get from the ipconfig command, and here is the dart code:
import 'dart:async';
import 'dart:io';
//Utilities that manage connections with server sockets.
//ServerUtil Class
class ServerUtil {
static const port = 6666;
static const host = MY_IP_GOES_HERE;
static late Socket socket;
static bool connected = false;
//a list of urls returned by the server
static List<String> urls = [];
//Constructor
ServerUtil() {
//Initialize the socket.
Socket.connect(host, port).then((Socket sock) {
socket = sock;
connected = true;
socket.listen(dataHandler,
onError: errorHandler, onDone: doneHandler, cancelOnError: false);
//send a message to the server.
}).catchError((e) {
print("Unable to connect: $e");
});
}
//Query method that sends a message to the server. The server will return a list of urls.
//The urls will be added to the urls list.
//The urls list will be returned.
static Future<List<String>> query(String userQuery) async {
urls.clear();
//check if socket is connected.
if (connected) {
//send the query to the server.
socket.writeln(userQuery);
await Future.delayed(const Duration(milliseconds: 200));
print(urls);
return urls;
}
//if socket is not connected, wait for 5 seconds and try again.
await Future.delayed(const Duration(milliseconds: 50));
return query(userQuery);
}
//Handles data from the server.
void dataHandler(data) {
//String of received data.
String dataString = String.fromCharCodes(data).trim();
//remove first and last character from the string.
dataString = dataString.substring(1, dataString.length - 1);
//remove all the whitespace characters from the string.
dataString = dataString.replaceAll(RegExp(r'\s+'), '');
urls = dataString.split(',');
}
//Handles errors from the server.
void errorHandler(error, StackTrace trace) {
print(error);
}
//Handles when the connection is done.
void doneHandler() {
socket.destroy();
}
}
This works perfectly fine while using a debug apk running it on my real Note 9 device. The problem however is that when I build a release apk and try it out, nothing happens.
The way I set it up is that I wait for the query method in an async and then I send the result to a new screen and push that screen into the navigator.
But in the release apk nothing happens, the new screen doesn't load.
So this leads me to my first question:
Is there a way to debug a release apk? see what exceptions it throws or print some stuff to console?
I have the server running on my Laptop, and the app runs on my phone which is on the same WIFI network.
My second question is:
Do I need to enable some sort of option with my router or my laptop to allow my phone to connect? it does connect in debug mode without any modifications
I tried some random things, like using 'localhost' instead of my IP, as I would normally connect say with a java client for example, but it didn't work.
My last question is:
Does the release apk or like android OS prevent connections to local hosts, maybe because it thinks it is not secure? but then it still connects in debug mode.
Thank you for your time.
Okay, I found this example in the book, so I know that this code is error free. The program below contains two classes, both of them are main classes. One is for client and one is for server.
According to the book, I'm supposed to compile them like this:
Compile client and server and then start server as follows:
$ java GreetingServer 6066
Waiting for client on port 6066...
Check client program as follows:
$ java GreetingClient localhost 6066
Connecting to localhost on port 6066
Just connected to localhost/127.0.0.1:6066
Server says Thank you for connecting to /127.0.0.1:6066
Goodbye!
I want to be able to run them on eclipse, but every time I do so, it's giving me this error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at GreetingServer.main(GreetingServer.java:47).
HOW CAN I RUN THIS PROGRAM IN ECLIPSE? Thanks.
// File Name GreetingClient.java
import java.net.*;
import java.io.*;
public class GreetingClient
{
public static void main(String [] args)
{
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try
{
System.out.println("Connecting to " + serverName
+ " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out =
new DataOutputStream(outToServer);
out.writeUTF("Hello from "
+ client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
// File Name GreetingServer.java
import java.net.*;
import java.io.*;
public class GreetingServer extends Thread
{
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException
{
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run()
{
while(true)
{
try
{
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to "
+ server.getRemoteSocketAddress());
DataInputStream in =
new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out =
new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to "
+ server.getLocalSocketAddress() + "\nGoodbye!");
server.close();
}catch(SocketTimeoutException s)
{
System.out.println("Socket timed out!");
break;
}catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
public static void main(String [] args)
{
int port = Integer.parseInt(args[0]);
try
{
Thread t = new GreetingServer(port);
t.start();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
See these lines
public static void main(String [] args)
{
String serverName = args[0]; //<-- Expecting a value
int port = Integer.parseInt(args[1]); //<-- Expecting a value
The args[] is a string array containing arguments that you pass via command line. And when you try to run it from eclipse directly, you arent specifying these values which results in args[] to be an empty array and thus args[0] gives an ArrayIndexOutOfBoundsException
To solve this, either create a run configuration from within eclipse (see screenshot)
and specify arguements that you want eclipse to pass when running this class. YOu can do this by right-clicking the project, select run, then run-configurations --> double click on java_application and pass in the information that you want. You may need to specify the main class name when specifying arguments so that eclipse can recognize which main class to pass args to.
OR you can just hardcode these values directly in the class itself (for testing)
You need to create a run configuration and pass the arguments there. Run the program in eclipse. Let it fail. This automatically creates a run configuration. Edit the configuration to add parameters. Or create a new run configuration.
I Tried to run a Java socket in mac with eclipse but it doesn't work. I got this error:
Exception in thread "main" java.net.BindException: Permission denied
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:521)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:414)
at java.net.ServerSocket.bind(ServerSocket.java:326)
at java.net.ServerSocket.<init>(ServerSocket.java:192)
at java.net.ServerSocket.<init>(ServerSocket.java:104)
at server.MessageServer.main(MessageServer.java:11)
How can i make it to run?
package server; //ChatServer
import java.io.*;
import java.net.*;
public class MessageServer {
public static void main (String args[]) throws IOException {
int port = 100;
ServerSocket server = new ServerSocket (port);
System.out.println("Server is started!");
while (true) {
Socket client = server.accept ();
System.out.println ("Accepted from " + client.getInetAddress ());
MessageHandler handler = new MessageHandler (client);
handler.start();
}
}
}
You can't open a port below 1024, if you don't have root privileges and from the code you posted in your comment, you seem to be trying to open port 100 which confirms my theory.
You need to use a port which is higher than 1024, if you're running the code under a non-root user.
Unix-based systems declare ports < 1024 as "privileged" and you need admin rights to start a server.
For testing, use a port number >= 1024.
When deploying the server in production, run it with admin rights.
I had the same issue and my port numbers were below 1024 changing port number to above 1024 solved my problem. Ports below 1024 are called Privileged Ports and in Linux (and most UNIX flavors and UNIX-like systems), they are not allowed to be opened by any non-root user.
Many systems declare ports that are less than 1024 as "admin rights" ports. Meaning, if you're only using this for basic testing use a higher port such as 2000. This will clear the exception that you're getting by running your current program.
int port = 100;
ServerSocket server = new ServerSocket (port);
Change that to something such as:
int port = 2000;
ServerSocket server = new ServerSocket (port);
MyServer.java
import java.io.*;
import java.net.*;
public class MyServer
{
ServerSocket ss;
Socket s;
DataOutputStream dos;
DataInputStream dis;
public MyServer()
{
try
{
System.out.println("Server Started ");
ss=new ServerSocket(4444);
s=ss.accept();
System.out.println(s);
System.out.println("Client Connected");
dis=new DataInputStream(s.getInputStream());
dos=new DataOutputStream(s.getOutputStream());
ServerChat();
}
catch(Exception e)
{
System.out.println(e);
}
}
public static void main(String arg[])
{
new MyServer();
}
public void ServerChat()throws IOException
{
String str;
do
{
str=dis.readUTF();
System.out.println("Client msg : "+str);
dos.writeUTF("Hello "+str);
dos.flush();
}while(!str.equals("stop"));
}
}
MyClient.java
import java.io.*;
import java.net.*;
public class MyClient
{
Socket s;
DataInputStream din;
DataOutputStream dout;
public MyClient()
{
try
{
s=new Socket("localhost",4444);
System.out.println(s);
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
ClientChat();
}
catch(Exception e)
{
System.out.println(e);
}
}
public void ClientChat() throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s1;
do
{
s1=br.readLine();
dout.writeUTF(s1);
dout.flush();
System.out.println("Server Msg : "+din.readUTF());
}while(!s1.equals("stop"));
}
public static void main(String arg[])
{
new MyClient();
}
}
Run Server program with root (Administrator).
Windows: Run as Administrator the IDE/Editor.
Ubuntu/macOS: sudo java...
This is an old question, and I might be replying too late, but I would like to anyways share my experience in case anyone hits the issue.
I was using port# 8000, but still unable to bind to the port from a java program. It was network filter running as part of eset endpoint security that was blocking the connection.
I added a rule in eset firewall to allow port 8000, and it started working.
I tried to create a simple chat via sockets and it works for LAN right now and for "localhost" too, of course, but not among different computers through the internet and thats the real point of a chat, isn't it!
socket = new Socket("--ip address--", 7345);
This line works for --ip address-- = localhost and --ip address-- = ""my local ip-address"", but with the ip address of my router, it throws a java.net.ConnectException
" java.net.ConnectException: Connection refused: connect "
I want to use my pc as server and not a real server, maybe there is the problem, but I think that there must be a solution. If that is an absurd simple question, don't doom me, because I'm a real newbie in network programming.
When you are creating a server, you have to use server socket with the ip address of where it's running...
The server socket needs to be running on your machine of your machine's ip address.
With your router, you need to forward the connections to the port you are running on your that is hosting the server.
Then you should be able to connect from outside your local network.
Without the code for what your are doing it's hard to tell if that's the only problem here is a simple chat server that might give you guidance.
import java.net.*;
import java.io.*;
public class ChatServer
{ private Socket socket = null;
private ServerSocket server = null;
private DataInputStream streamIn = null;
public ChatServer(int port)
{ try
{
System.out.println("Binding to port " + port + ", please wait ...");
server = new ServerSocket(port);
System.out.println("Server started: " + server);
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted: " + socket);
open();
boolean done = false;
while (!done)
{ try
{ String line = streamIn.readUTF();
System.out.println(line);
done = line.equals(".bye");
}
catch(IOException ioe)
{
done = true;
}
}
close();
}
catch(IOException ioe)
{ System.out.println(ioe);
}
}
public void open() throws IOException
{ streamIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}
public void close() throws IOException
{ if (socket != null) socket.close();
if (streamIn != null) streamIn.close();
}
public static void main(String args[])
{ ChatServer server = null;
if (args.length != 1)
System.out.println("Usage: java ChatServer port");
else
server = new ChatServer(Integer.parseInt(args[0]));
}
}
I am creating a multithread server program to display the browser's request when it try to connect to localhost.
I found only IE9 on my Windows works as expected but not Firefox 19, Chrome, Opera. The are simply sitting there to wait for my program response.
What I have missed?
import java.io.*;
import java.net.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HTTPEchoServer {
private static final String serverName = "HTTPEchoServer";
private static final int port = 80;
private static final String CRLF = "\r\n";
private static final Logger logger = Logger.getLogger(serverName);
private static void printHeader(PrintWriter out) {
out.println("HTTP/1.0 200 OK\r\n" + "Server: " + serverName + CRLF
+ "Content-Type: text/html" + CRLF + CRLF
+ "<!DOCTYPE HTML PUBLIC "
+ "\"-//W3C//DTD HTML 4.0 Transitional//EN\">\n"
+ "<HTML>\n"
+ "<HEAD>\n"
+ " <TITLE>" + "HTTP Echo Server Result</TITLE>\n"
+ "</HEAD>\n"
+ "<H1>HTML Received from HTTP Echo Server</H1>\n"
+ "<B>Here is the request sent by your browser:</B>\n"
+ "<PRE>");
}
private static void printTrailer(PrintWriter out) {
out.println("</PRE>\n" + "</BODY>\n" + "</HTML>\n");
}
static class ClientHandler extends Thread {
Socket socket = null;
public ClientHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
logger.log(Level.INFO, "Accepted client {0}:{1}",
new Object[]{socket.getInetAddress(), socket.getPort()});
try {
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
try (PrintWriter writer = new PrintWriter(os, true)) {
synchronized (this) {
printHeader(writer);
writer.flush();
BufferedReader reader = new BufferedReader
(new InputStreamReader(is));
String line;
while ((line = reader.readLine()) != null) {
writer.println(line);
writer.flush();
}
printTrailer(writer);
writer.flush();
writer.close();
}
}
socket.close();
} catch (IOException ex) {
logger.log(Level.SEVERE, null, ex);
}
logger.log(Level.INFO, "Disconnected client {0}:{1}",
new Object[]{socket.getInetAddress(), socket.getPort()});
}
}
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(port);
logger.log(Level.INFO, "Server started, listening at port {0} ...", port);
ExecutorService executor = Executors.newCachedThreadPool();
while (true) {
Socket socket = server.accept();
ClientHandler handler = new ClientHandler(socket);
executor.execute(handler);
}
} catch (IOException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
}
Also, I found I cannot run this program on the OS X unless I change the port to 8080. I have already disabled the firewall on my OS X 10.8.2 computer. The error I get is:
<pre>
java.net.BindException: Permission denied
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:376)
at java.net.ServerSocket.bind(ServerSocket.java:376)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at HTTPEcho.HTTPEchoServer.main(HTTPEchoServer.java:80)
</pre>
You cannot open server socket in applet in all browsers except MSIE. This is done because opening server socket is security violation. If you do want to do this you have to sign your applet.
I hope that I understood your correctly that your code is running in applet environment (because you mentioned browsers) although I cannot see this facet from your stack trace that starts from main().
EDIT:
I read your post again and understood that your question actually contains 2 questions: first about applets and second about running as application under Unix. For unix #Anders R. Bystrup gave you the answer: only root can listen to ports under 1024. So, you have to run your program as root or using sudo.
BTW it seems that you are on the wrong way. Could you probably explain what would you like to achieve and community probably can give you a tip for better solution.
As the exception itself says java.net.BindException: Permission denied. You need to be root user to bind ports below 1024. If you are on linux you san do sudo java HTTPEchoServer to start the server.
Other possibility may be that you already have a server running on port 80.
Port 80 is reserved HTTP port, there are other ports aswell which are reserved.
ports 1 through 1023 for administrative functions leaving port numbers greater than 1024 available for use.
How to find available port