1.很简单的客户端-服务器模式。在局域网下测试没有没问题。C-S之间可以实现通信。但如果通过公网连接就是不行,压根客户端连不到服务器。
代码如下。只写监听、连接部分。
服务器端:
newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server_port = 7000;
IPAddress serverIP = IPAddress.Parse("220.131.112.45");
localEP = new IPEndPoint(serverIP, server_port);
try {
//绑定
newsock.Bind(localEP);
//监听
newsock.Listen(10);
//开始接受连接,异步。
newsock.BeginAccept(new AsyncCallback(OnConnectRequest), newsock);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
2.这里就有个问题,如果bind的公网IP的话。压根服务器bind就会出错,报“在其上下文中,该请求的地址无效”错误。
3.如果将公网IP地址,变成IPAddress.Any,则可以bind并启动监听。但客户端,使用公网IP和端口连接不上。报"由于连接放在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败"错误
客户端:
newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string ipadd ="220.131.112.45";
int port = 7000;
IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ipadd), port);
try
{
newclient.Connect(ie);
}
catch (SocketException e)
{
MessageBox.Show("连接服务器失败 " + e.Message);
return;
}
4.值得说明的是本机的端口是做了端口映射的。220.131.112.45和7000是我举例的IP和端口非实际的。不用再测试IP是否能ping通和或在线测试端口是否打开了。有个相同功能的软件可以在本机使用,也是用的此IP和端口。而且也用了一款软件来测试否是公网IP状态和是否端口映射,显示是没错的。
------解决思路----------------------
localEP = new IPEndPoint(serverIP, server_port);
你确定这里填写serverIP?
bind表示你要监听的IP和端口
你设置成serverIP,就是只有从这个IP来的数据包才侦听,其他IP来的数据包都直接丢弃了
你应该填写IPAddress.Any才对啊
------解决思路----------------------
对于外网和内网,服务端程序并无区别
问题是你得有外网IP,才行
如果你是通过路由器连接的外网,那么你需要在路由器里做映射,将路由器的外网IP映射到你内网的服务端所在的IP
也就是说,外网数据包发给路由器之后,路由器必须得能够将数据包转发给你的服务端才行
毕竟你的程序是放在计算机上,而不是路由器里
除非你计算机直接连外网,那么就不需要设置任何东西