使用花生壳和TP-LINK路由器搭建外网访问内网服务器的平台

来源:互联网 发布:怎么删除我的淘宝评价 编辑:程序博客网 时间:2024/05/17 00:53

首先说明,本文所述的这种方法,只适用于你的服务器(PC机)具有公网IP的情况,也就是说,你的服务器每次上网时分配到的公网IP可以是动态变化的,但必须要分配到一个公网IP。

1、看服务器是否具有公网IP

由于国内电信运营商的公网IP资源日益缺乏,因此有些运营商通过做NAT转发,让部分用户公用一个出口来减轻公网IP的需求压力,如果你的服务器是通过这样的形式来上网的话,就叫做没有公网IP,其表现为路由器wan口IP与www.ip138.com查询到的IP不一致。

进入服务器接入网络的TP-Link路由器,在 WAN口状态——网关 中可以看到一个IP地址

在百度上搜索“IP”,或者进入www.ip.cn,www.ip138.com 之类的网站,又可以看到一个IP地址

如果这两个IP地址相同,说明服务器具有公网IP,可以适用本文的方法。

2、注册花生壳

花生壳的官网:http://www.oray.com/

注册一个账号,然后系统会免费分配给你一个二级域名(这个过程可能需要填写姓名、身份证、电话等信息)。

注册成功后,登录花生壳官网,进入会员中心(https://console.oray.com/),点击“域名管理”(https://console.oray.com/domain/root/)进入如下界面


选中你的域名,点击“启用花生壳”。

在这里可以查看花生壳公网版的各种级别的服务(http://hsk.oray.com/price/),如果不购买收费服务,默认使用免费版。

3、路由器设置

进入TP-LINK路由器,点击左侧的的“动态DNS”


进入对花生壳的设置,在此输入你在花生壳中注册的用户名和密码,点击登录,稍等一会,当连接状态变为“连接成功”,同时域名信息中显示出你的域名后,说明已经成功登录,点击保存。


再进入TP-LINK路由器的 转发规则——虚拟服务器 中,添加一个新条目,如下图所示


其中,IP地址一栏填写你的服务器的内网IP地址(不太确定如果服务器设置了DHCP上网,内网IP随机分配的话,这样做是否还有效。但如果服务器设置为固定内网IP的话,这样肯定没问题),服务端口填写你要对外提供访问的应用程序的端口。

4、程序检验

为了检验服务器是否真的可以在外网访问,下面用C#编写了两个很简单的socket小程序,一个服务端,运行在服务器上,一个客户端,运行在要访问服务端的机器上(为了省事,也可以在服务器端运行测试)。

服务器端程序

using System.Net.Sockets;using System.Net;using System.Threading;using System.Text;using System;  namespace SocketServer{    class Program    {        private static byte[] result = new byte[1024];        private static int myProt = 20147;   //端口          static Socket serverSocket;        static void Main(string[] args)        {            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            serverSocket.Bind(new IPEndPoint(IPAddress.Any, myProt));  //绑定IP地址:端口              serverSocket.Listen(10);    //设定最多10个排队连接请求              Console.WriteLine("服务端启动:监听{0}成功", serverSocket.LocalEndPoint.ToString());            //通过Clientsoket发送数据              Thread myThread = new Thread(ListenClientConnect);            myThread.Start();            Console.ReadLine();        }        /// <summary>          /// 监听客户端连接          /// </summary>        private static void ListenClientConnect()        {            while (true)            {                Socket clientSocket = serverSocket.Accept();                Console.WriteLine("接收开始");                try                {                    //通过clientSocket接收数据                      int receiveNumber = clientSocket.Receive(result);                    Console.WriteLine("接收客户端{0}消息{1}", clientSocket.RemoteEndPoint.ToString(), Encoding.ASCII.GetString(result, 0, receiveNumber));                    Console.WriteLine("接收完毕,准备发送返回值");                    clientSocket.Send(Encoding.ASCII.GetBytes("OK"));                    Console.WriteLine("发送完毕");                }                catch (Exception ex)                {                    Console.WriteLine("服务端程序Socket即将关闭,原因:" + ex.Message);                    clientSocket.Shutdown(SocketShutdown.Both);                    clientSocket.Close();                    break;                }                            }        }    }}

客户端程序

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net;using System.Net.Sockets;using System.Threading;namespace SocketClient{    class Program    {        private static byte[] result = new byte[1024];                static void Main(string[] args)        {            string defaultServerAddress = "127.0.0.1";            int defaultPort = 20147;            Console.WriteLine("请输入服务器地址,直接回车则使用默认地址(" + defaultServerAddress + ")");            string serverAddress = Console.ReadLine();            if (String.IsNullOrEmpty(serverAddress))            {                serverAddress = defaultServerAddress;            }            Console.WriteLine("请输入服务器端口号,直接回车则使用默认地址(:" + defaultPort + ")");            string portString = Console.ReadLine();            int port;            if (String.IsNullOrEmpty(portString))            {                port = defaultPort;            }            else            {                port = Convert.ToInt32(portString);            }                        //设定服务器IP地址              IPAddress ip;            bool ret = IPAddress.TryParse(serverAddress, out ip);            Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            try            {                if (ret)    //是IP                {                    Console.WriteLine("您当前设置的服务器为{0}:{1}", ip, port);                    clientSocket.Connect(new IPEndPoint(ip, port)); //配置服务器IP与端口                  }                else        //是域名                {                    Console.WriteLine("您当前设置的服务器为{0}:{1}", serverAddress, port);                    clientSocket.Connect(serverAddress, port); //配置服务器IP与端口                  }                Console.WriteLine("连接服务器{0}:{1}成功", serverAddress, port);            }            catch(Exception e)            {                Console.WriteLine("连接服务器{0}:{1}失败,请按回车键退出!", serverAddress, port);                Console.WriteLine("故障原因:" + e.Message);                while (true) ;                return;            }            //通过 clientSocket 发送数据              try            {                string sendMessage = "client send Message Hellp" + DateTime.Now;                clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage));                Console.WriteLine("向服务器发送消息:{0}" + sendMessage);            }            catch (Exception ex)            {                Console.WriteLine("客户端程序Socket即将关闭1:" + ex.Message);                clientSocket.Shutdown(SocketShutdown.Both);                clientSocket.Close();            }            //通过clientSocket接收数据              try            {                int receiveLength2 = clientSocket.Receive(result);                Console.WriteLine("接收服务器消息:{0}", Encoding.ASCII.GetString(result, 0, receiveLength2));            }            catch (Exception ex)            {                Console.WriteLine("客户端程序Socket即将关闭2:" + ex.Message);                clientSocket.Shutdown(SocketShutdown.Both);                clientSocket.Close();            }            Console.WriteLine("发送完毕,按回车键退出");            clientSocket.Shutdown(SocketShutdown.Both);            clientSocket.Close();            Console.ReadLine();        }    }}

运行结果:


0 0
原创粉丝点击