Skip to main content
gamedev.net
🔒 Locked

basic sockets help...

Started by temp_ie_cant_thinkof_name Oct 31, 2004 at 12:06 AM 12 replies 900+ views
Original Post
temp_ie_cant_thinkof_name
temp_ie_cant_thinkof_name
This is using Java's Socket and I/O stream classes, but my problem could probably easily be solved by someone who's used sockets in C or even someone who knows what they're doing on the network (ie not me). Here's the relevant code:

        Socket echoSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;
        String hostName = "YODA"; // "127.0.0.1" // "149.169.87.78" // "localhost"

        try {
			echoSocket = new Socket(hostName, 7);
			out = new PrintWriter(echoSocket.getOutputStream(), true);
			in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
		}
		catch (UnknownHostException e) {
			System.out.println("Can't connect to host: " + hostName);
			System.exit(1);
		}
		catch (IOException e) {
			System.out.println("Can't create I/O for connection to: " + hostName);
			System.exit(1);
		}

Link to sun tutorial i'm going by. Here's a quote from the java api reference also on the java.sun site:
Quote:
getOutputStream public OutputStream getOutputStream() throws IOException Returns an output stream for this socket. If this socket has an associated channel then the resulting output stream delegates all of its operations to the channel. If the channel is in non-blocking mode then the output stream's write operations will throw an IllegalBlockingModeException. Returns: an output stream for writing bytes to this socket. Throws: IOException - if an I/O error occurs when creating the output stream or if the socket is not connected.
My problem: I'm getting the IOException. That is, IOException is being thrown by either of these lines:

			out = new PrintWriter(echoSocket.getOutputStream(), true);
			in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
That is, if you comment out the "in =" statement the exception will be thrown. And if you comment out the "out =" the exception will be thrown. And the Socket(hostName, port) constructor is working I believe, because if you put anything else as the host, like "omghikthx", the UnknownHostException will be thrown. So AFAIK I'm connecting alright, but I just can't create an I/O stream from the socket. The program (if you didn't analyze the sun tutorial) works by creating an input (taking input from the net) and an output (sending output to the net) stream on the same socket, so the EchoClient prog is both a an echo client and echo server. The network I'm on is at a uni dorm, and my IP is assigned via DHCP. So everything you see here:

String hostName = "YODA"; // "127.0.0.1" // "149.169.87.78" // "localhost"
i've tried: YODA is the host name I get by doing an ipconfig /all on WinXP console; 149.169.87.78 is the local IP assigned by the LAN here. Don't know if that makes a difference, though... I haven't tried changing the port number yet. Could 7 be reserved? (yes, I know, i'm a newb, etc.) Thanks for your time. I hope I explained it all enough.
"I study differential and integral calculus in my spare time." -- Karl Marx
Programmer One
Programmer One
I'm not really sure how Java does it, but it could be that there is already something else listening on port 7. Or maybe it can't resolve the host address...
temp_ie_cant_thinkof_name
temp_ie_cant_thinkof_name
I remembered something about "restricted ports under 1000" and dug back into the tutorial to find this:
Quote:

Port numbers range from 0 to 65,535 because ports are represented by 16-bit numbers. The port numbers ranging from 0 - 1023 are restricted; they are reserved for use by well-known services such as HTTP and FTP and other system services. These ports are called well-known ports. Your applications should not attempt to bind to them.

So I guess I should try a port number 1023 < n < 65,536. But that begs the question, why would the the same tutorial that said that 7 is restricted go ahead and use 7??
"I study differential and integral calculus in my spare time." -- Karl Marx
temp_ie_cant_thinkof_name
temp_ie_cant_thinkof_name
Um, is there by any chance a better way to do this, b/c my current code is:
        Socket echoSocket = null;        PrintWriter out = null;        BufferedReader in = null;        String hostName = "YODA"; // "127.0.0.1" // "149.169.87.78" // "localhost"		int port;        for(port = 0; port < 65536; port++) {			try {				echoSocket = new Socket(hostName, port);				out = new PrintWriter(echoSocket.getOutputStream(), true);				in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));			}			catch (UnknownHostException e) {				System.out.println("Can't connect to host: " + hostName);				// System.exit(1);			}			catch (IOException e) {				System.out.println("Can't create I/O for connection to: " + hostName);				// System.exit(1);			}		}		if(port == 65536) {			System.out.println("No port number worked, ie, WTF++?!?");			System.exit(1);		}		System.out.print("\n\n  Port number " + port + " works!");

and it seems to be taking one second per connection/stream attach, which translates to > 18 hours o_O

edit:
I guess limiting the ports to > 1023 will help a little, but it still seems to me that the port number isn't the problem, b/c I don't think ports 1024 to 1100 would be used up which is what it's gotten to so far :(
        Socket echoSocket = null;        PrintWriter out = null;        BufferedReader in = null;        String hostName = "YODA"; // "127.0.0.1" // "149.169.87.78" // "localhost"		int port;		final int portMin = 1024;		final int portMax = 65535;        for(port = portMin; port <= portMax; port++) {			try {				echoSocket = new Socket(hostName, port);				out = new PrintWriter(echoSocket.getOutputStream(), true);				in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));			}			catch (UnknownHostException e) {				System.out.println("port: " + port);				System.out.println("Can't connect to host: " + hostName);				System.out.println();				// System.exit(1);			}			catch (IOException e) {				System.out.println("port: " + port);				System.out.println("Can't create I/O for connection to: " + hostName);				System.out.println();				// System.exit(1);			}		}		if(port == 65536) {			System.out.println("No port number worked, ie, WTF++?!?");			System.exit(1);		}		System.out.print("\n\n  Port number " + port + " works! \n");
"I study differential and integral calculus in my spare time." -- Karl Marx
temp_ie_cant_thinkof_name
temp_ie_cant_thinkof_name
Oh yeah, I forgot to say that I turned off the windows firewall and disabled Norton Anti-Virus (?), thinking maybe those guys were guarding the ports...

edit: didn't restart or try turning off any other service, though...
"I study differential and integral calculus in my spare time." -- Karl Marx
temp_ie_cant_thinkof_name
temp_ie_cant_thinkof_name
Okay, I've commented out the
/* catch (IOException e) {				System.out.println(e.getMessage());				System.out.println("port: " + port);				System.out.println("Can't create I/O for connection to: " + hostName);				System.out.println();				// System.exit(1);			}*/

so that exceptions will be caught by VM and messages printed. (Make sure throws IOException clause is put after main()). Here's the call trace:
Exception in thread "main" java.net.ConnectException: Connection refused: connect	at java.net.PlainSocketImpl.socketConnect(Native Method)	at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)	at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:364)	at java.net.Socket.connect(Socket.java:507)	at java.net.Socket.connect(Socket.java:457)	at java.net.Socket.<init>(Socket.java:365)	at java.net.Socket.<init>(Socket.java:178)	at EchoClient.main(EchoClient.java:42)

At line 42 in my code is new Socket(hostName, port), so there IS an exception being thrown from that and it's not the UnknownHost. So I have the host names right, but for some reason I cannot connect to them. The throwing of the IOException is actually being caused by the call to Socket()!!! not the I/O stream creation lines!!! So indeead I am not connecting and don't know why...
"I study differential and integral calculus in my spare time." -- Karl Marx
temp_ie_cant_thinkof_name
temp_ie_cant_thinkof_name
Quote:
Original post by oddbot
Quote:

Using netstat I only see ~2O ports being used. Again, I'm *not* running an echo server, the client is the echo server.


Woah, I think you're missing something about how this all works. Clients need to have a server to talk to, ill try and give you a bit of a rundown.

[rundown]

Hope that helps,
-oddbot


I see how that works, but that's not how you implement it in Java. The Socket class does the listening and connecting for you and buffers what's passed through the socket. So the code is right, heck it was written and published by sun, but for some reason Socket is not connecting. Let me reread the tutorial though to make sure that I don't need an extra server running.
"I study differential and integral calculus in my spare time." -- Karl Marx
oddbot
oddbot
Uhm, if you dont have an echo server running it's not going to connect. Try something basic like: www.google.com and port 80 or your university's homepage address is. Or run your own echo server, not sure if windows comes with one ?

-oddbot
temp_ie_cant_thinkof_name
temp_ie_cant_thinkof_name
OMG, I DESERVE TO BE CALLED AN IDIOT SO I WILL DO IT MYSELF: I AM AN IDIOT++!!!~

Upon reading the tutorial once more I found that my notion of "the client is the server" is totally false. I don't know but that's just what I got out of it the first time through. However, as I clicked on to the next tutorial "Creating the Server Side of the Socket" I was reassured of my idiotic thick-headedness. Thank you for tolerating me. Rating++ for you all
"I study differential and integral calculus in my spare time." -- Karl Marx
temp_ie_cant_thinkof_name
temp_ie_cant_thinkof_name
Okay, I've confirmed that I'm connecting I think (but to no avail of the original problem). I've changed my code to this. Actually here's all the code:
import java.io.*;import java.net.*;public class EchoClient {    public static void main(String[] args) throws IOException {        /*        Socket echoSocket = null;        PrintWriter out = null;        BufferedReader in = null;        String hostName = "129.219.17.5";        try {            echoSocket = new Socket(hostName, 7);            out = new PrintWriter(echoSocket.getOutputStream(), true);            in = new BufferedReader(new InputStreamReader(                                        echoSocket.getInputStream()));        break;  // don't forget the stopping case!        } catch (UnknownHostException e) {            System.err.println("Don't know about host: taranis.");            System.exit(1);        } catch (IOException e) {            System.err.println("Couldn't get I/O for "                               + "the connection to: taranis.");            System.exit(1);        }        */		if(args.length != 1) {			System.out.println("Usage: java EchoClient hostName");			System.exit(0);		}		Socket echoSocket = null;        PrintWriter out = null;        BufferedReader in = null;        String hostName = args[0]; // "YODA" // "127.0.0.1" // "149.169.87.78" // "localhost"		int port;		final int portMin = 1024;		final int portMax = 65535;        for(port = portMin; port <= portMax; port++) {			try {				echoSocket = new Socket(hostName, port);				out = new PrintWriter(echoSocket.getOutputStream(), true);				in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));          break;			}			catch (UnknownHostException e) {				System.out.println("port: " + port);				System.out.println("Can't connect to host: " + hostName);				System.out.println();				// System.exit(1);			}			catch (IOException e) {				System.out.println("port: " + port);				System.out.println("Can't create I/O for connection to: " + hostName);				System.out.println();				// System.exit(1);			}		}		if(port == 65536) {			System.out.println("No port number worked, ie, WTF++?!?");			System.exit(1);		}		System.out.print("\n\n  Port number " + port + " works! \n");		BufferedReader stdIn = new BufferedReader(                                   new InputStreamReader(System.in));		String userInput;		while ((userInput = stdIn.readLine()) != null) {	  	  out.println(userInput);	  	  System.out.println("echo: " + in.readLine());		}		out.close();		in.close();		stdIn.close();		echoSocket.close();    }}

It reads in the host name from the cmd line args. I've again tried all of: YODA, 149.169.87.78, 127.0.0.1, localhost, and they all seem to be correct b/c the UnknownHostException is never thrown. BUT, if you change the host name to "hi" or "oryg4ol" (ie a non-sense word) then the UnknownHostException will be thrown and "Can't connect to host will be printed." I don't however know if that means I made a connection or not... What's interesting is I tried host names like "hello" (common English words) and they existed on the network!! (B/c UnknownHostEx. wasn't thrown) Well, I am in a college dorm...

@oddbot: I am connecting to an echo server, the same socket is the server AND the client as I said and as is explained in this tutorial I doing: Reading/Writing to Sockets. I will connecting to google on port 80 right now...

edit: I forgot the all-important break line in that loop, but it doesn't make a difference on the problem, b/c it was never reached anyway.
"I study differential and integral calculus in my spare time." -- Karl Marx
oddbot
oddbot
No worries dude, have fun with your sockets :)
oddbot
oddbot
If you are running an echo server, and it is on port 7, try:
telnet localhost 7

and type some junk.

To see what sockets are in use, use the netstat command.

-oddbot
temp_ie_cant_thinkof_name
temp_ie_cant_thinkof_name
Using netstat I only see ~2O ports being used. Again, I'm *not* running an echo server, the client is the echo server. I am
1. creating a socket on a port.
1b. taking user input, what's to be echoed.
2. writing to the socket, what was input.
(assuming I actually created the output stream which is what is
currently not working AFAIK, connecting is working fine)
3. reading from the socket.
4. printing what was read from the socket, the echo'd input.

So you see, the echo server "cannot" even be made because the line:
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));

is throwing the IOException (ie, not working). These I/O stream classes are not deprecated and are *what's used* to do file I/O or any type of I/O, so I don't think I need to switch to anything else. I will however see what's causing the exception--getInputStream() or InputStreamReader().
"I study differential and integral calculus in my spare time." -- Karl Marx
oddbot
oddbot
Quote:

Using netstat I only see ~2O ports being used. Again, I'm *not* running an echo server, the client is the echo server.


Woah, I think you're missing something about how this all works. Clients need to have a server to talk to, ill try and give you a bit of a rundown.

Server:    Binds a socket, eg 7.    Listens on socket for new connectionsClient:    Connects to server on port 7Server:    Accepts connectionClient    Writes "Hello"Server:    Reads "Hello"    Writes: "You said 'hello'"Client:    Reads "You said 'hello'"    Closes socketServer:    Closes socket    Waits for another connection



Hope that helps,
-oddbot

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.