tags:

views:

126

answers:

4

I'm not able to connect a simple client and a simple server. When I run the server there doesn't seem to be any problem, but when I try to send it data with the client it throws an exception saying that it didn't connect within a timeout period.

Here is the server code I'm using:

    public void server()
    {
        try
        {
            byte[] bytes = new byte[1024];
            int bytesReceived = 0;
            String message = "";
            IPAddress direction = IPAddress.Parse(getIPExternal()); //getIPExternal return the public IP of the machine in which the programm runs
            IPEndPoint directionPort = new IPEndPoint(direction, 5656);
            Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socketServer.Bind(directionPort);
            socketServer.Listen(100);
            while (true)
            {
                Socket client = socketServer.Accept();
                bytesReceived = client.Receive(bytes);
                message = System.Text.Encoding.Unicode.GetString(bytes, 0, bytesReceived);

                editMultiline.Invoke(new writeMessageDelegate(writeMessage), new object[] { message, "client"}); //Ignore this, it is just to show the info in a textbox because the server code runs in a diferent thread

                client.Shutdown(SocketShutdown.Both);
                client.Close();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Server error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

This way I get the public IP from the machine on which the program runs:

    public string getIPExternal()
    {
        string direction;
        WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
        WebResponse response = request.GetResponse();
        StreamReader stream = new StreamReader(response.GetResponseStream());
        direction = stream.ReadToEnd();
        stream.Close();
        response.Close();

        //Search for the ip in the html
        int first = direction.IndexOf("Address: ") + 9;
        int last = direction.LastIndexOf("</body>");
        direction = direction.Substring(first, last - first);

        return direction;
    }

And here is my client code:

    public void client(string directionIP, string message) //directionIP is the IP from the computer to which i want to get connected
    {
        try
        {
            byte[] bytesSend = System.Text.Encoding.Unicode.GetBytes(message);
            IPAddress direction = IPAddress.Parse(directionIP);
            IPEndPoint directionPort = new IPEndPoint(direction, 5656);
            Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socketClient.Connect(directionPort);
            socketClient.Send(bytesSend);
            socketClient.Close();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Client error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

Any suggestion would be great.

+1  A: 

Id suggest looking into the TcpListener and TcpClient class, instead of playing around with sockets.. the Tcp* class's do all that stuff for you

Tommy
Ok, i will check them out.
ezgar
+1  A: 

Getting the public IP implies that you are behind a NAT device (like a simple home router). Have you ensured that the device is forwarding TCP connections to port 5656 to the server machine and the server's firewall has been configured as well?

dpp
Yes, i have done it.
ezgar
+1  A: 

Please try this code. Maybe without the resource leaks, it will work better:

public void server()
{
    try
    {
        byte[] bytes = new byte[1024];
        IPAddress direction = IPAddress.Parse(getIPExternal()); //getIPExternal return the public IP of the machine in which the programm runs
        IPEndPoint directionPort = new IPEndPoint(direction, 5656);
        using (Socket socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            socketServer.Bind(directionPort);
            socketServer.Listen(100);
            while (true)
            {
                using (Socket client = socketServer.Accept())
                {
                    int bytesReceived = client.Receive(bytes);
                    String message = System.Text.Encoding.Unicode.GetString(bytes, 0, bytesReceived);

                    editMultiline.Invoke(new writeMessageDelegate(writeMessage), new object[] { message, "client" }); //Ignore this, it is just to show the info in a textbox because the server code runs in a diferent thread

                    client.Shutdown(SocketShutdown.Both);
                }
            }
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString(), "Server error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

public string getIPExternal()
{
    WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
    string direction;
    using (WebResponse response = request.GetResponse())
    {
        using (Stream responseStream = response.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(responseStream))
            {
                direction = reader.ReadToEnd();
            }
        }
    }

    //Search for the ip in the html
    int first = direction.IndexOf("Address: ") + 9;
    int last = direction.LastIndexOf("</body>");
    return direction.Substring(first, last - first);
}

abd the client:

public void client(string directionIP, string message) //directionIP is the IP from the computer to which i want to get connected
{
    try
    {
        byte[] bytesSend = System.Text.Encoding.Unicode.GetBytes(message);
        IPAddress direction = IPAddress.Parse(directionIP);
        IPEndPoint directionPort = new IPEndPoint(direction, 5656);
        using (Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            socketClient.Connect(directionPort);
            socketClient.Send(bytesSend);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString(), "Client error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}
John Saunders
Ok, i will check your code; thanks.
ezgar
+1  A: 

There is plenty of room for failure here. The odds that the client would be able to guess the server's IP address are slim, unless you type it in by hand. It would have to run on another network as well. Consider using the local IP address if you are testing this with two machines close together, 127.0.0.1 if you are testing this on the same machine. And the port number is almost certainly blocked by your firewall. You'll have to make an explicit exception for it.

Hans Passant
Yes, the IP address from the server is introduced by the user in a textbox; and i have disable the firewall.
ezgar
So, how many machines do you use, what does the network look like, and have you tried 127.0.0.1? The rest of my answer matters too.
Hans Passant