小编The*_*uad的帖子

在3G上没有经过UDP打孔

我正试图在软件中实现一个打孔功能.问题是,我正在使用已经建立的TCP服务器与用户进行通信.

这是我到目前为止所拥有的:

  • "A"向UDP服务器"US"发送消息(在端口9333上)
  • "US"将已连接的端口发送回"A"(端口31000 - localport 31005)
  • "A"向TCP服务器"TS"发送消息,说他想要连接到B(并给端口31000)
  • "TS"向"B"发送消息,给他"A"的端口(31000)和ip
  • "B"向"US"发送消息(在端口9333上)
  • "US"向"B"发送消息,告诉他他的端口45000(localport 45005)
  • "B"向"TS"发送消息给出是udp端口(45000)
  • "TS"向"A"发送消息,给出B的udp端口(45000)和ip
  • "A"开始在端口45000上向B的ip发送udp消息,并在localport 31005上收听
  • "B"开始向端口31000上的A的IP发送udp消息,并在localport 45005上收听

当然,例如端口31000,31005,45000和45005,每个端口改变的新连接,只有9333是静态的.

我知道有很多来回,比实际情况还要多.事实上,我必然会使用TCP服务器与两个用户进行通信,udp服务器只是将用户的端口返回给自己,因此它可以将其发送回TCP服务器.

但是,任何人都不会收到用户之间的消息......任何人都会知道为什么?


编辑:

我用http://nattest.net.in.tum.de/test.php测试了我的路由器,并且udp打孔工作正常,所以问题不是来自我的路由器,而是来自我的协议......

当用户在同一个NAT后面时,一切正常,当然它使用了private ip,但这意味着代码也在工作,所以每一个都会导致协议问题......


编辑2:

实际上,我做了一半的工作(问题实际上来自我的代码,而不是协议......我已经连接了2个用户,一个用3G连接iPhone,一个连接在Wifi上我的NAT.

有趣的(不是那么多)事情是,只有一个套接字能够在两个用户之间接收和发送数据.(由iphone发起的套接字)根据协议,我应该有2个连接良好的套接字,我错了吗?

所以我设法在我的NAT中打了一个洞,但实际上并没有在蜂窝NAT中.

当然,我立即测试了2台连接在3G上的iphone.没有人得到另一个人的信息.

我错过了有关手机NAT的内容吗?

PS:很抱歉更新我的问题,但由于我没有得到答案,我试图自己找...

PS 2:因为我设法在我的NAT中打了一个洞,我改变了标题,加上"在3G上"


编辑3:我再次运行http://nattest.net.in.tum.de/test.php测试,我的电脑通过我的iphone的3G连接连接到互联网.

这是结果: UDP HOLE PUNCHING RESULT

显然所有的udp打孔测试都是在第9次测试中成功的.

似乎还有更多:

UDP绑定测试(?):端点独立绑定,端口预测很容易

因此,通过3G连接连接2个对等设备应该不会有任何问题(远远不及"家庭"NAT背后)......我是对的吗?


编辑4:

为了确定,我现在向两个不同的UDP服务器发送消息,以检查3G上的端口和本地端口是否相同.

长话短说,端口(本地和公共)在两台服务器上连接时都是一样的.所以在EDIT 2上完成的测试是正确的,udp是端点独立的,所以我不应该在进行打孔时遇到任何问题......(至少我的ISP)

udp 3g hole-punching 3g-network

33
推荐指数
2
解决办法
1万
查看次数

boost asio async_write:如何不交错async_write调用?

这是我的实现:

  • 客户端A为客户端B发送消息
  • 服务器通过async_read适当数量的数据处理消息,并等待来自客户端A的新数据(为了不阻止客户端A)
  • 随后服务器将处理该信息(可能是做一个MySQL查询),然后将消息发送到客户端B async_write.

问题是,如果客户端A发送消息的速度非常快,async_writes则会在调用前一个async_write处理程序之前进行交错.

有一种简单的方法可以避免这个问题吗?

编辑1:如果客户端C刚刚在客户端A之后向客户端B发送消息,则应出现相同的问题...

编辑2:这会有用吗?因为它似乎阻止了,我不知道在哪里......

 namespace structure {                                                              
  class User {                                                                     
  public:                                                                          
    User(boost::asio::io_service& io_service, boost::asio::ssl::context& context) :
      m_socket(io_service, context), m_strand(io_service), is_writing(false) {}    

    ssl_socket& getSocket() {                                                      
      return m_socket;                                                             
    }                                                                              

    boost::asio::strand getStrand() {                                              
      return m_strand;                                                             
    }                                                                              

    void push(std::string str) {                                                   
      m_strand.post(boost::bind(&structure::User::strand_push, this, str));        
    }                                                                              

    void strand_push(std::string str) {                                            

      std::cout << "pushing: " << boost::this_thread::get_id() << std::endl;       
      m_queue.push(str);                                                           
      if (!is_writing) {                                                           
        write();                                                                   
        std::cout << "going to write" << std::endl;                                
      }                                                                            
      std::cout << "Already writing" …
Run Code Online (Sandbox Code Playgroud)

c++ asynchronous boost-asio

26
推荐指数
2
解决办法
2万
查看次数

VarChar(255)和VarChar(65536)之间的MySQL不同处理

有谁知道使用VarChar(255)和VarChar(65536)之间的区别?

这是我目前所知道的:

  • VarChar(255)只使用一个字节的大小
  • VarChar(65536)将使用两个字节的大小
  • VarChar(65536)仅在MySQL 5.0.3之后才存在
  • MySQL使用255和65536之间的不同处理(虽然不知道区别)

我不确定这些varchars之间是否有任何性能差异.

假设我想创建一个具有多种类型行的表.使用带有'data_type1'和'data_type2'的枚举

varchar中的data_type1永远不会超过255个字符data_type2在varchar中的字符数通常超过255个

哪个解决方案表会更好?

id (int) - autoincrement
type (enum : data_type1, data_type2)
msg (varchar(255))
data (TEXT)
Run Code Online (Sandbox Code Playgroud)

在type == data_type2时只使用'data'列?

要么

id (int) - autoincrement
type (enum : data_type1, data_type2)
msg (varchar(65536))
Run Code Online (Sandbox Code Playgroud)

使用'msg'列存在什么类型?

实际上,对于用于治疗目的的两种溶液都需要类型列.

编辑:

当type == data_type2时,存储的数据实际上永远不会超过10000个字符

编辑2:

我不打算在列msg和数据中搜索

这是一个关于存储性能的简单问题,而不是索引或搜索性能......

mysql varchar

12
推荐指数
1
解决办法
2万
查看次数

如何获取Video AVAsset的大小(KB)

我想获得一个AVAsset视频文件大小,而不是视频的分辨率,但文件重量是KB.

一个解决方案是从持续时间和estimatedDataRate计算估计的文件大小,但这似乎只是为了获得文件大小.

我已经检查了嵌入AVAssetTrack其中的所有数据似乎没有在那里.即使是估计的文件大小也会很好.

ios avasset

12
推荐指数
3
解决办法
7542
查看次数

c ++ boost :: thread在主线程上执行代码?

在调用boost :: thread运行一些指令后,是否有可能回到主线程?

我的代码基于proactor模式,但是某个函数可能需要一些时间,所以为了不阻塞整个程序,我正在创建一个运行这个函数的线程.当这个函数结束时,我需要调用另一个函数,但它必须在主线程上运行.我有一个连接池,这不是线程安全的,我真的想避免互斥.

有没有一种稳定的方法在主线程上运行一个函数(在另一个线程上调用)?

就像在ObjectiveC performSelectorOnMaintThread中一样

c++ boost-thread

10
推荐指数
2
解决办法
3990
查看次数

Erlang接受SSL连接的速度非常慢(与C++相比)

我目前正在使用Erlang编写的一段代码测试极端条件.

我已经实现了learnyousomeerlang.com的主管技术,具有多种接受能力.

这里稍微修改了代码以处理主管的SSL连接:

-module(mymodule).

-behaviour(supervisor).

-export([start/0, start_socket/0]).
-define(SSL_OPTIONS, [{active, true},
              {mode, list},
              {reuseaddr, true},
              {cacertfile, "./ssl_key/server/gd_bundle.crt"},
              {certfile, "./ssl_key/server/cert.pem"},
              {keyfile, "./ssl_key/server/key.pem"},
              {password, "********"}
             ]).

-export([init/1]).

start_link() ->
    application:start(crypto),
    crypto:start(),
    application:start(public_key),
    application:start(ssl),
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init([]) ->
    {ok, LSocket} = ssl:listen(4242, ?SSL_OPTIONS),
    spawn_link(fun empty_listeners/0),
    {ok, {{simple_one_for_one, 60, 3600},
      [{socket,
        {mymodule_serv, start_link, [LSocket]}, % pass the socket!
        temporary, 1000, worker, [mymodule_serv]}
      ]}}.

empty_listeners() ->
    [start_socket() || _ <- lists:seq(1,100)],
    ok.

start_socket() ->
    supervisor:start_child(?MODULE, []).
Run Code Online (Sandbox Code Playgroud)

这是gen_server的代码,它代表每个连接的客户端:

-module(mymodule_serv).
-behaviour(gen_server).

-export([start_link/1]).
-export([init/1, handle_call/3, …
Run Code Online (Sandbox Code Playgroud)

sockets erlang ssl

10
推荐指数
1
解决办法
1558
查看次数

使用Erlang的最佳,最有效的客户端池技术是什么

我是一个真正的Erlang新手(1周前开始),我正在尝试通过创建一个小而有效的聊天服务器来学习这种语言.(当我说效率时,我的意思是我有5台服务器用于对数十万个连接客户端进行压力测试 - 百万将是很棒的!)

我找到了一些教程这样做,唯一的是,我找到的每个教程都是IRC之类的.如果一个用户发送邮件,则除发件人之外的所有用户都将收到邮件.我想稍微改变一下,并使用一对一的讨论.

搜索连接用户的最有效客户端池是什么?我考虑过注册这个过程,因为它似乎做了我需要的一切,但我真的不认为这是更好的方法.(或者最好的方式去做).

有人会有这样的建议吗?

编辑:

每个连接的客户端都会受到ID的影响.

当用户连接时,它首先发送一个登录命令来给它的id.当用户想要将消息发送给另一个消息时,该消息看起来像这样

[ID-NUMBER][Message] %% ID-NUMBER IS A FIXED LENGTH

当我要求"最有效的客户端池"时,我实际上正在寻找在连接的客户端列表上检索/添加/删除一个客户端的最快方法,这可能很大(数十万 - 可能是数百万)

编辑2:

回答一些问题:

  • 我正在使用Raw Socket(现在使用telnet与服务器通信) - 稍后可能会转移到ssl ...
  • 这是我自己的协议
  • 每个客户都是一个衍生出来的Pid
  • 每个客户端的Pid都链接到它自己的监视器(主要是出于调试原因 - 如果断开连接,客户端应该从头开始auth重新连接)
  • 我在开始编码之前已经阅读了几本书,所以我还没有掌握Erlang的各个方面,但我并没有意识到它,我会在需要时阅读更多关于它的信息.
  • 我真正想要的是存储和搜索PID以便直接从进程到进程发送消息的最佳方法.

我应该使用列表编写自己的搜索客户端功能吗?

或者我应该使用ets?

甚至使用register/2 unregister/1和whereis/1来维护我的客户端列表,使用它的唯一id作为atom,它似乎是最简单的方法,我真的不知道它是否有效,但我我很确定这是丑陋的解决方案;-)?

sockets erlang client-server server-side

7
推荐指数
1
解决办法
1288
查看次数

哪个集群NoSQL DB用于消息存储目的?

还有一个关于NoSQL选择的问题.但是,我还没有找到有人要求这种目的,消息存储......

我有一个Erlang聊天服务器,我已经使用MySQL存储好友列表,以及"JOIN needed"信息.

我想存储消息(用户因为离线而没有收到消息......)并检索它们.

我已经预先选择了NoSQL,我不能使用像MongoDB这样的东西,因为它是面向RAM的范例,并且不能像其他人一样集群.我想我的列表中有3个选项:

  • HBase的
  • 了Riak
  • 卡桑德拉

我知道他们的模型不同,一个使用键/值,另一个使用SuperColumns和co.

到目前为止,由于它是Erlang的稳定客户端库,我对Riak有偏好.

我知道我可以使用Cassandra和Thrift,但是对于Erlang来说似乎不太稳定(我没有得到很好的回报)

我现在对HBase一无所知,只知道它存在并且基于像Cassandra和Riak这样的Dynamo.

所以这就是我需要做的事情:

  • 每个注册用户存储1到X条消息.
  • 获取每个用户存储的消息数.
  • 一次检索用户的所有消息.
  • 一次删除用户的所有消息.
  • 删除所有超过X个月的邮件

现在,我对那些NoSQL DB真的很陌生,我一直都是MySQL爱好者,这就是为什么我问你这个问题,作为一个新手,会有比我更多经验的人帮我选择哪一个更好,并且会让我做我想做的一切,不用太麻烦......

谢谢 !

erlang hbase cassandra nosql riak

7
推荐指数
1
解决办法
2445
查看次数

使用Poison将地图编码为json时的顺序键

出于阅读目的,我想在json文件中有一个特定的键顺序.

我知道地图的密钥没有任何顺序,然后我们不应该依赖它,但由于Poison无法编码支持者,我不知道如何做到这一点.

iex(1)> %{from: "EUR", to: "USD", rate: 0.845} |> Poison.encode!
"{\"to\":\"USD\",\"rate\":0.845,\"from\":\"EUR\"}"
Run Code Online (Sandbox Code Playgroud)

我想要的结果是:

"{\"from\":\"EUR\", \"to\":\"USD\", \"rate\":0.845}"
Run Code Online (Sandbox Code Playgroud)

我应该使用哪种结构来实现毒药?

elixir elixir-poison

7
推荐指数
1
解决办法
865
查看次数

Linux上最大套接字数

似乎服务器限制在~32720个套接字......我已经尝试了每个已知的变量来提高这个限制.但服务器仍然限制在32720打开套接字,即使仍然有4Go的空闲内存和80%的空闲cpu ...

这是配置

~# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 63931
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 798621
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 2048
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63931
virtual memory …
Run Code Online (Sandbox Code Playgroud)

sockets pthreads

6
推荐指数
1
解决办法
2万
查看次数