草庐IT

c# - 与 C# 服务器的 Android TCP 通信 -> socket.Close

coder 2023-09-17 原文

我有一个 Android 客户端和一个 C# 服务器。它们通过套接字进行通信,C# 服务器异步处理接收。

通信本身没有问题。我可以在服务器上对客户端进行身份验证并相互发送消息。但是如果我尝试通过

关闭客户端上的套接字
socket.close();

服务器收到空数据包的“垃圾邮件”。一旦 OutputStream 关​​闭,就会发生这种情况。

这是我的 Android 客户端代码:

public void run()
{ 
    try
    {                   
        InetAddress serverAddr = InetAddress.getByName(pServerIp);            
        Socket socket = new Socket(serverAddr, pServerPort);
        try 
        {
            OutputStream socketoutstr = socket.getOutputStream(); 
            OutputStreamWriter osr = new OutputStreamWriter( socketoutstr ); 
            bw = new BufferedWriter( osr ); 

            InputStream socketinstr = socket.getInputStream(); 
            InputStreamReader isr = new InputStreamReader( socketinstr ); 
            br = new BufferedReader( isr );                      

            User tmp = Login("SESAM", "PASSWORD");
            if(tmp != null)
            {
                Log.e("TCP", "Login succeeded!");
                user = tmp;
            }
            else
            {
                Log.e("TCP", "Login failed!");
                socket.close();
            }
        } 
        catch(Exception e) 
        {
            Log.e("TCP", "S: Error", e);
            socket.close();
        } 
        finally 
        {
        }
    } 
}

这是我的服务器代码中处理传入数据的部分:

private void WaitForData()
{
    try
    {
        WorkerCallback = new AsyncCallback(OnDataReceived);

        UndefinedPacket packet = new UndefinedPacket();
        socket.BeginReceive(packet.DataBuffer, 0, packet.DataBuffer.Length, SocketFlags.None, WorkerCallback, packet);
    }
    catch (SocketException se)
    {
        Console.WriteLine(se.Message);
    }
}

private void OnDataReceived(IAsyncResult asyn)
{
    UndefinedPacket socketData = (UndefinedPacket)asyn.AsyncState;
    try
    {
        int CharCount = socket.EndReceive(asyn);
        char[] chars = new char[CharCount];

        System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
        String text = System.Text.Encoding.UTF8.GetString(socketData.DataBuffer);
        int charLen = d.GetChars(socketData.DataBuffer, 0, CharCount, chars, 0);

        String data = new String(chars);
        if (data.Length > 0)
        {
            IClientPacket packet = PacketFactory.GetInstance(data);
            server.PacketManager.AddIncomingPacket(packet, this);
        }
        Console.WriteLine("Received Data!");
        WaitForData();
    }
    catch (ObjectDisposedException)
    {
        Console.WriteLine("OnDataReceived: Socket has been closed");
        server.RemoveWorkerSocket(this);
    }
    catch (SocketException se)
    {
        if (se.ErrorCode == 10054) // Connection reset by peer
        {
            string msg = "Client Disconnected";
            Console.WriteLine(msg);
            server.RemoveWorkerSocket(this);
        }
        else
        {
            Console.WriteLine(se.Message);
            server.RemoveWorkerSocket(this);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        server.RemoveWorkerSocket(this);
    }            
}

当我关闭 Android 模拟器时,我收到正确的服务器消息:“客户端已断开连接”。

但是当我关闭 Outputstream 或客户端上的整个套接字时,OnDataReceived() 会被非常快速地重复调用,data.length 为“0”。

感谢您的帮助!

最佳答案

它不是空的“数据包”(请注意,TCP 是一个)- 从 TCP 套接字读取零字节意味着另一端关闭了连接,因此您也应该关闭您的一端。

此处的“客户端断开连接”可能是 RST 的结果当模拟器出现故障并切断所有连接时从模拟器中获取。

关于c# - 与 C# 服务器的 Android TCP 通信 -> socket.Close,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7031260/

有关c# - 与 C# 服务器的 Android TCP 通信 -> socket.Close的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  5. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  6. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  7. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  8. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  9. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

  10. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

随机推荐