I wrote a simple client-server application. It works very well on my computer. but when my friend tries to connect my server he can't. I create the server on my computer with port 23. Here is the part of creating the server:
public Server(int port_number) throws IOException{
create_Server(port_number);
}
public static void main(String[] args) throws IOException {
int port_number=23;
new Server(port_number);
}
private void create_Server(int port_number) throws IOException{
ss = new ServerSocket(port_number);
System.out.println("Server is ready!");
while(true){
s=ss.accept();
System.out.println(s.getLocalAddress().getHostName() + " was connected!");
send_con_mes();
list.put(s,new DataOutputStream(s.getOutputStream()) );
new ServerThread(s,this).start();
}
}
and here is the client part ;
public void start_Chat() {
try {
Ip_addr = JOptionPane.showInputDialog("Enter the IP number of the server to connect : ");
s = new Socket(Ip_addr, 23);
Client_name = JOptionPane.showInputDialog("Enter your Nickname : ");
dis = new DataInputStream(s.getInputStream());
dos = new DataOutputStream(s.getOutputStream());
new Thread(Client.this).start();
well I can talk, send private messages etc. When I connect to server on my computer as clients, but the final problem is a client from another IP cannot get connected.
You have to configure your network to allow this port to be accessed. This means enabling firewall on you PC, and your routers etc. There is nothing you can do in Java to avoid having to get this right first.
EDIT: If the other machine is trying to connect to you via an Internet router they will have to use your public IP address rather than your internal PC address. If you don't know your public address you can use a site like http://whatismyipaddress.com/. Unless you have a static IP address it can change when you reconnect. (One reason to stay connected all the time)
Related
I am Running into a java.net.BindException: Address already in use (Bind failed) on a server-client socket app
I am trying to learn about Java sockets using a Youtube tutorial as a reference. My code seems to match everything in the video (except variables names) but, when trying to run the server and then the client sockets, I get:
Exception in thread "main" java.net.BindException: Address already in use (Bind failed)
I have tried even printing out the local port just to make sure I connect to the right available port but, nothing works. Is there any documentation I can look into to solve this problem? or any guidance?
Server.java
public class serverSocket {
public static void main(String args[]) throws IOException{
String message, serverResponse;
ServerSocket serverSocket = new ServerSocket(56789);
System.out.print(serverSocket.getLocalPort());
Socket acceptClientRequestSocket = serverSocket.accept();
Scanner serverScanner = new Scanner(acceptClientRequestSocket.getInputStream());
message = serverScanner.next();
System.out.println(message);
serverResponse = message.toUpperCase();
PrintStream newMessage = new PrintStream(acceptClientRequestSocket.getOutputStream());
newMessage.println(serverResponse);
}
}
Client.java
public class clientSocket {
public static void main(String args[]) throws UnknownHostException, IOException {
String message,outputMessage;
Scanner clientInput = new Scanner(System.in);
Socket clientSocket = new Socket("localhost",56789);
Scanner incomingStream = new Scanner(clientSocket.getInputStream());
System.out.println("Enter a message");
message = clientInput.next();
PrintStream printClientStream= new PrintStream(clientSocket.getOutputStream());
printClientStream.println(message);
outputMessage = incomingStream.next();
System.out.println(outputMessage);
}
}
Is there any documentation I can look into to solve this problem? or any guidance?
You have probably your previously exectued program still running. Check the running java processes. Kill the the previous one and try again.
If this wouldn't help try restarting your machine. If the problem persists after that then some service is already running on this port and is starting with the OS. In that case you can either change the port number in your app or disable that service.
For approximately one week I have been trying to create a simple chat-program to learn how to use datagrams and sockets, proceeding with success I'm now trying to make a more functional final version of it, to test what I have learned but I have run into a huge problem.
Sending packets between two local computers is easy as a breeze, but when it comes to sending them to other computers on the internet port-forwarding have been an issue. Looking into this I discovered UPnP and created an automatic UPnP port on the client using Cling to make it more user-friendly, server-side I always port-forward "manually", which means it can always receive under normal circumstances. but the client is facing a problem I didn't anticipate: they can't receive datagrams through the UPnP port. if you port forward them "manually" they can receive (they can always send though, and the server reads them loud and clear).
So my question is: can someone show me how to send/receive (don't know if it's the servers fault or the clients fault, problem lies either in how the server receives, or how the client sends) through UPnP ports? or am I using UPnP ports all wrong? my router, which is the test subject, have UPnp port enabled, and I have tested UDP and TCP ports along with datagramsockets and multicastsockets in every configuration I could think of.
TL:DR use UPnP or find other solution on how to send/receive datagrams through a router/modem.
I am extremely sorry if the code is a bit messy/buggy, not the full code, will post pastebin if asked.
Client:
public class Client {
public MulticastSocket rsocket = new MulticastSocket(25566);
public Client() throws IOException {
//creating UPnP port using Cling...
InetAddress inet = InetAddress.getLocalHost();
PortMapping desiredMapping = new PortMapping(25566,
inet.getHostAddress(), PortMapping.Protocol.UDP,
"Chatt program");
UpnpServiceImpl upnpService = new UpnpServiceImpl(
new PortMappingListener(desiredMapping));
upnpService.getControlPoint().search();
// loop the loop to get values from text fields used
// to receive messages from the server.
//point of interest, this is where the client should receive data, works on a normal
//portforward, doesn't on a UPnP port, no idea why.
byte[] info = new byte[256];
while (true) {
DatagramPacket receive = new DatagramPacket(info, info.length);
rsocket.receive(receive);
String rmessage = new String(receive.getData(), 0,receive.getLength());
System.Out.println(rmessage);
}
}
public static void main(String[] args) throws IOException {
new Client();
}
}
Server:
public class Server {
public MulticastSocket rsocket = new MulticastSocket(25565);
public Server() throws IOException {
String rmessage = new String("a message");
// send to clients, not working on UPnP port
send(rmessage, 25566);
}
public void send(String msg, int port) throws IOException {
byte[] message = msg.getBytes();
DatagramPacket gpacket = new DatagramPacket(message,message.length, address, 25566);
rsocket.send(gpacket);
}
public static void main(String[] args) throws IOException {
new Server();
}
}
I made one android application that needs to connect one local database provided by wamp server. First using the android virtual device (AVD) my IP to connect the server first time used to be: 10.0.2.2. My AVD was connecting fine, but when I tried to connect direct on my device he wasn't finding the local server with this 10.0.2.2 IP. At this point I've changed IP to 192.168.1.5 which was my LAN cable IP, both device and AVD were running without problems... but sometimes I need to change my connection to wifi, which changes the IP..also, I realized that fix one IP in my source code will be a problem to release the android app, since other people will have other LAN IP address.
To solve this problem, I've started to look for a solution, such as acquire the LAN IP dynamically. For this purpose I built this Java application as test:
public class test {
public static void main(String[] args) throws Exception
{
String roundHost = null;
Enumeration<NetworkInterface> n = NetworkInterface.getNetworkInterfaces();
for (; n.hasMoreElements();)
{
NetworkInterface e = n.nextElement();
Enumeration<InetAddress> a = e.getInetAddresses();
for (; a.hasMoreElements();)
{
InetAddress addr = a.nextElement();
if (addr.isSiteLocalAddress()){
String pureHost = addr.getByName(addr.getHostName()).toString();
roundHost = addr.getHostAddress();
pureHost = pureHost.substring(addr.getHostName().length()+1);
if(!roundHost.equals(pureHost))
break;
}
}
}
System.out.println(roundHost);
}
}
As output, this java application gives me my correct LAN wifi IP or even my LAN cable IP which is 192.168.1.3 or 192.168.1.7. From here I made one "IPParser" to use on my android app:
public class IPParser {
String pureHost, roundHost = null;
public IPParser() throws UnknownHostException{
Enumeration<NetworkInterface> n = null;
try {
n = NetworkInterface.getNetworkInterfaces();
} catch (SocketException e1) {
e1.printStackTrace();
}
for (; n.hasMoreElements();)
{
NetworkInterface e = n.nextElement();
Enumeration<InetAddress> a = e.getInetAddresses();
for (; a.hasMoreElements();)
{
InetAddress addr = a.nextElement();
if (addr.isSiteLocalAddress()){
pureHost = addr.getByName(addr.getHostName()).toString();
roundHost = addr.getHostAddress();
pureHost = pureHost.substring(addr.getHostName().length()+1);
if(!roundHost.equals(pureHost))
break;
}
}
}
}
public String returnIp() {
return roundHost;
}
}
As you can see it's pretty similar; the difference is just some structural changes to adapt the needed syntax. And now comes the real problem: When I try to run this parser inside my AVD, my ip is 10.0.2.15 and running directly in my device the ip return is 192.168.1.6 - Obviously the android app is crashing because it can't find the local server to connect.
My IP config information:
I'm not an expert in network, so I ask, take it easy and if I said something technically wrong or adjacents please edit and correct me..finally I ask:
Why this is happening and what's possible to do to solve this problem?
The IPs you mention (10.0.2.2 and 192.168.1.5) are from two different networks, which makes sense since the documentation states that:
Each instance of the emulator runs behind a virtual router/firewall
service that isolates it from your development machine's network
interfaces and settings and from the internet. An emulated device can
not see your development machine or other emulator instances on the
network. Instead, it sees only that it is connected through Ethernet
to a router/firewall.
The virtual router for each instance manages the 10.0.2/24 network
address space — all addresses managed by the router are in the form of
10.0.2., where is a number. Addresses within this space are pre-allocated by the emulator/router as follows:
What this means is that when using the AVD there is a virtual network that is created which the device and the computer are part of. In your case your local machine takes the address 10.0.2.2 in this virtual network and the AVD 10.0.2.15. But when you connect directly through your device, the computer's IP (as well as the device's) is in the LAN's address space (i.e. 192.168.1.5 and 192.168.1.6).
The code you posted resolves the IP address of the host, but if you want the device to resolve automatically the server's IP address and you can guarantee they will always be both connected to the same LAN, then you can use multicast UDP messages (I didn't find a really good source but you can start here, here and here). This type of communication sends a UDP datagram to the network to a specific multicast IP address and port, to which other devices in the network are listening. I've used this scheme in an Android application that needed to find a computer in the network so I know for a fact that it works. I can share some code if you need to.
EDIT
The following snippets of code are the ones that implement the search of computers in the network. The Android application this was used in could control the mouse and keyboard of any computer in the network that had the server application running.
Android Client
public void findComputers(View v) {
try {
int port = 4444;
String multicastAddr = "224.168.1.0";
DatagramSocket socket = new DatagramSocket(port);
socket.setSoTimeout(300);
InetAddress group = InetAddress
.getByName(multicastAddr);
DatagramPacket packet = new DatagramPacket(new byte[] { 1 }, 1,
group, port);
socket.send(packet);
// Give time to the servers to respond
Thread.sleep(100);
while (true) {
try {
// Listen for the servers responses
byte[] buffer = new byte[256];
packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
String data = new String(packet.getData());
// Information sent from servers include the host's name
// and IP addres separated by a semicolon.
String[] parts = data.split(";");
// Add a server to the result list.
Computer computer = new Computer(parts[1].trim(),
parts[0].trim());
this.computers.put(computer.getName(), computer);
} catch (InterruptedIOException ex) {
break;
}
}
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
String output = "No computers found.";
if (this.computers.size() > 0) {
output = this.computers.size() + " computer(s) found.";
this.fillComputers();
}
Toast.makeText(this, output, Toast.LENGTH_SHORT).show();
}
Server
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
/**
* Receives UDP broadcast packets in the default port requesting for server name
* and IP, broadcasting the information in return.
*
* #author jfacorro
*
*/
public class NameResolverService extends Thread {
private InetAddress localAddress = null;
private byte[] localAddressData = null;
private MulticastSocket socket = null;
private boolean exit = false;
public NameResolverService() {
}
public void exit() {
this.exit = true;
this.socket.close();
}
#Override
public void run() {
try {
int port = 4444;
String multicastAddr = "224.168.1.0";
// Get current address
this.localAddress = InetAddress.getLocalHost();
this.socket = new MulticastSocket(port);
InetAddress group = InetAddress.getByName(multicastAddr);
this.socket.joinGroup(group);
this.localAddressData = (this.localAddress.getHostAddress() + ";" + this.localAddress
.getHostName()).getBytes();
} catch (IOException ex) {
this.notified.notified(ex.getMessage());
ex.printStackTrace();
}
while (!this.exit) {
try {
byte[] buffer = new byte[1];
DatagramPacket packet = new DatagramPacket(buffer,
buffer.length);
socket.receive(packet);
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(this.localAddressData,
this.localAddressData.length, address, port);
socket.send(packet);
} catch (IOException e) {
if(!this.exit)
e.printStackTrace();
}
}
this.socket.close();
}
}
I'm trying to setup a protected client and protected server connection using sockets. Whenever I run the program I receive a connection error saying the connection was refused. I'm using Java in Eclipse IDE running on MAC OS. Any ideas why this code cannot connect to my localhost?
Protected Client:
public static void main(String[] args) throws Exception
{
String host = "localhost";
int port = 7999;
String user = "George";
String password = "abc123";
Socket s = new Socket(host, port);
ProtectedClient client = new ProtectedClient();
client.sendAuthentication(user, password, s.getOutputStream());
s.close();
}
Protected Server
public static void main(String[] args) throws Exception
{
int port = 7999; //7999
ServerSocket s = new ServerSocket(port);
Socket client = s.accept();
ProtectedServer server = new ProtectedServer();
if (server.authenticate(client.getInputStream()))
System.out.println("Client logged in.");
else
System.out.println("Client failed to log in.");
s.close();
}
When I run the program I receive the following error:
Exception in thread "main" java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:382)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:241)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:228)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:431)
at java.net.Socket.connect(Socket.java:527)
at java.net.Socket.connect(Socket.java:476)
at java.net.Socket.<init>(Socket.java:373)
at java.net.Socket.<init>(Socket.java:216)
at ProtectedClient.main(ProtectedClient.java:36)
I have gotten this error before when using particular sockets. Try a different socket like 5687. (Or if you need that particular socket, try making sure your firewall allows it).
Make sure you call client.close() on the server as well. If your program worked once it might be blocking that port.
Following is a thread which has a SOCKET listening at port 15445.
Whenever a Datagram packet is sent to it, it forwards back to the sender's address after adding a String(Reply from SERVER) in it. I want this code to run somewhere on the Internet, but I don't know where to start.
Is it possible? Can I run this code on a Tomcat server or do I need to do something different?
import java.io.*;
import java.net.*;
public class HelloWorld extends Thread {
protected DatagramSocket socket = null;
protected BufferedReader in = null;
public HelloWorld() throws IOException {
socket = new DatagramSocket(15445);
}
public void run() {
while (true) {
try {
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
InetAddress address = packet.getAddress();
int port = packet.getPort();
String s = "Reply from SERVER";
byte[] b= s.getBytes();
packet = new DatagramPacket(b, b.length, address, port);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
new HelloWorld().start();
}
}
No, Tomcat isn't a web server. It's a servlet/JSP engine that happens to have an HTTP server built in.
This looks like POJO with a main. Why can't you just run that as a service? Why do you think you need a web server?
Use Jetty (echo server is one of the tutorials afaik) and expose your port to the internet.
If your code works fine forward the necessary port through your router so it's reachable from the internet. If your looking for a hosted solution, vservers are a cheap way to start. http://www.superuser.com is the place to go for network configuration.