Sockets in .NET don't get connected
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);
开发者_如何学JAVA 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.
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
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?
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);
}
}
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.
精彩评论