www.2527.com_澳门新葡8455手机版_新京葡娱乐场网址_
做最好的网站

TCP连接并相互,Linux下游戏代理VPN化解方案

2019-05-18 21:19 来源:未知

1. 服务器(一个连接的情况)

 

package com.machuang.tcp;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTcp {

    public static void main(String[] args) throws IOException {
        // 创建 socket, 指定端口号
        ServerSocket server = new ServerSocket(8888);

        // 等待客户端连接,阻塞式,直到有客户端连接,才会执行该语句并往下执行
        Socket socket = server.accept();

        // 输出 连接成功 的提示
        System.out.println("一个客户端已连接");

        /*    
        //// 发送一个数据到客户端
        String msg = "欢迎连接";
        BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( socket.getOutputStream() ) );

        // 写出数据
        bw.write(msg);
        bw.newLine(); // 添加一个换行
        bw.flush();
        */

        // 使用 DataOutputStream 方法发送数据
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());

        // 写数据
        dos.writeUTF("欢迎连接");
        dos.flush();


    }

}

 

前言:

简述

对于一个C/S结构的程序,客户端有些时候需要实时得知与服务器的连接状态。而对于客户端与服务器断开连接的因素很多,现在就目前遇到的情况进行一下总结。

2. 客户端

package com.machuang.tcp;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientTcp {

    public static void main(String[] args) throws UnknownHostException, IOException {
        // 创建 socket, 需指定服务器地址和端口号
        Socket client = new Socket("localhost", 8888);

        /*
        //// 接收服务器的数据,注意,使用 Buffered 方法时,是逐行读取
        BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
        String echo = br.readLine();
        */

        // 使用 DataInputStream 方法接收数据
        DataInputStream dis = new DataInputStream(client.getInputStream());

        String receivedStr = dis.readUTF();

        // 显示接收到的数据
        System.out.println(receivedStr);
    }

}

 

目前一些游戏服务器缺少镜象服务器,在国内访问国外的游戏服务器很慢。为了解决因地域或线路不同而导致网络速度慢,玩游戏容易卡机的情况,以前大部分使用代理方式,使用SOCK代理通过代理服务器访问游戏,通过SOCK代理达到提速的效果,但越来越多的游戏限制使用SOCK方式。对于这种情况,很多代理公司通过VPN技术来实现代理效果。用户拨入到VPN服务器后,通过VPN服务器访问游戏服务器,对用户完全透明,用户端软件不需要做任何设置。稳定且高效。

分为下面六种不同情况

  1. 客户端网线断开
  2. 客户端网络断开
  3. 客户端通过HTTP代理连接服务器,代理机器断开代理
  4. 客户端通过HTTP代理连接服务器,代理机器的网络断开
  5. 客户端通过HTTP代理连接服务器,代理机器的网线断开
  6. 服务器断开

3. 服务器(多个连接的情况)

package com.machuang.tcp;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTcpMultiConncetion {

    public static void main(String[] args) throws IOException {
        // 创建 socket, 指定端口号
        ServerSocket server = new ServerSocket(8888);

        while(true) {
            // 等待客户端连接,阻塞式,直到有客户端连接,才会执行该语句并往下执行
            Socket socket = server.accept();

            // 输出 连接成功 的提示
            System.out.println("一个客户端已连接");

            // 使用 DataOutputStream 方法发送数据
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());

            // 写数据
            dos.writeUTF("欢迎连接");
            dos.flush();    
        }



    }

}

 

实现方案:

同时对于以上六种情况又分为连接服务器之前和连接上服务器之后,下面就分别对不同的情况进行分析。

通过VPN方式来实现。逻辑拓扑图如下:

开始连接服务器之前

1、 客户端网线断开 
此时用socket调用connectToHost方法连接服务器会立即触发QTcpSocket的error信号,我们可以绑定相应的槽去处理连接失败的结果。


2、 客户端网络断开 
3、 客户端通过HTTP代理连接服务器,代理机器断开代理 
4、 客户端通过HTTP代理连接服务器,代理机器的网络断开 
5.、客户端通过HTTP代理连接服务器,代理机器的网线断开 
6、 服务器断开 
此时用socket调用connectToHost方法连接服务器并不会立即触发QTcpSocket的error信号,而是经过40s 的连接等待超时发出error信号,见下图。

图片 1


图片 2

已经连接上服务器

1、 客户端网线断开 
此时socket不会发送error信号,也不会发送disconnect信号,查询资料是因为网线断开是属于物理链路层,tcp无法察觉到,socket仍处于连接状态。


2、 客户端网络断开 
3、 客户端通过HTTP代理连接服务器,代理机器断开代理 
4、 客户端通过HTTP代理连接服务器,代理机器的网络断开 
5.、客户端通过HTTP代理连接服务器,代理机器的网线断开

第二和第三种情况下会立即触发error信号,而第四和第五种情况下会等待30s左右会发送error信号。


6、 服务器断开 
此时socket会发送disconnect信号,可以绑定相应的槽去处理服务器断开的情况。

1、 方案1:

检测与服务器断开的另外方法

对于有些程序(客户端)需要立即知道与服务端连接状态,而不是等待几十秒之后才有信号通知到或者根本就检测不出与服务器断开,除了利用QTcpSocket提供的信号(有几种情况不会发出信号或发出信号延迟),这里列出另外几种处理方法。

1、发送心跳包,即客户端每隔一段时间发送一条报文,报文不需附带具体内容,只需要让服务端知道这是一条心跳报文,并回发一条消息,客户端收到这条消息后就得知与服务器保持连接的状态。

适用情况:

检测本地网络,定义一个时钟,每次timeout去检测本地的网络,关于怎么判断本地网络是否通畅呢?

2、可以用windows提供的IsNetworkAlive方法,返回为false为网络异常。加上头文件为#include “Sensapi.h”。同时需要包含Sensapi.lib。 
(通过IsNetworkAlive方法判断本地网络,在客户端已经连接上服务器,并且禁用网络时会立即发送error信号,在error信号绑定的槽中去调用这个方法发现返回值为true,因为这种情况下禁用网络后会立即发送error信号,调用IsNetworkAlive方法时可能立即检测不到网络异常。如果通过断点的方式,在调用IsNetworkAlive时就会返回false)

    DWORD dwFlag;
    if (FALSE == IsNetworkAlive(&dwFlag))
    {
        qDebug() << "NetWorkError";
    }

用户连接VPN服务器速度较快,但连接游戏服务器慢,VPN服务器连接游戏服务器快

注意:

但是这种方法,在本地存在虚拟机并且虚拟机开启时会失效,因为IsNetworkAlive会检测本地所有的网络,在网线断开后,可能检测到虚拟机网络正常,导致返回ture。

3、如果有自己的服务器就ping服务器(前提服务器不会挂),否则就ping一个相对可靠的IP (比如百度),通过看他ping的结果怎么样. 
同时在C 实现 ping 功能&& 域名(URL)解析实际 IP地址 这篇博客中用C 实现了 ping的 功能,有兴趣的小伙伴可以看一看,了解一下。

QProcess *cmd = new QProcess;
cmd->start("ping www.baidu.com");
// 等待ping 的结果
while (cmd->waitForFinished())
{
    QString result = QString::fromLocal8Bit(cmd->readAll());
    qDebug() << result;
}

QHostInfo::lookupHost("www.baidu.com", this, SLOT(lookedUp(QHostInfo)));

void lookedUp(QHostInfo &host)
{
     qDebug() << host.addresses().first().toString();
}
//得到IP 地址 就是在互联网上 如果不能得到 就不行

4、QNetworkConfigurationManager::isOnline()。 
当然这个只能检查你是否有网络链接,而不能检测你是否连接到互联网。


对于需要自动重连的客户端可以通过以上方法,在判断出与服务器断开后可以重新连接,或者通过超时定时器进行重连,方法很多,在于尝试。

 

 

采用方案:

则让用户拨入VPN服务器后通过VPN服务器连接游戏服务器,这样可以提高用户连接游戏服务器的速度

2、 方案2:

适用情况:

如果用户连接中转服务器(如国内IDS机房服务器)快,连接VPN服务器慢,连接游戏服务器也慢,但VPN服务器连接游戏服务器快

采用方案:

可让用户通过中转服务器拨入到VPN服务器,然后通过VPN服务器访问游戏服务器

安装与配置:

1、 用户端:不用windows自带的客户端程序,采用定制的专用客户端,用户只需双击安装即可

2、 中转服务器(可选):可采用Linux作中转服务,也可采用windows系统,从稳定角度,采用Linux系统较好。根据情况,中转服务器可安装多台或仅一台。

3、 VPN服务器:建议采用Linux系统,可进行流量控制和NAT设置。根据情况,VPN服务器安装多台或仅一台

4、 认证服务器:采用radius验证,数据库存在于数据库中。管理用户可用web后台管理界面进行操作:新建帐户、设置过期日期、设置IP地址、设置连接数等等各项设置。认证服务器一般只需一台,提供用户认证、日志查询及登录控制。

图片 3

TAG标签:
版权声明:本文由澳门新葡8455手机版发布于计算机编程,转载请注明出处:TCP连接并相互,Linux下游戏代理VPN化解方案