草庐IT

C# 套接字 : Client Mishandle 'a' as the Client's id

coder 2023-09-19 原文

有两个我制作的程序无法运行。有服务器和客户端。服务器通过给用户一个 ID(从 0 开始)来接受许多客户端。服务器根据服务器的 ID 将命令发送到特定的客户端。 (示例:200 个客户端连接到 1 个服务器。服务器选择的 ID 为“5”,因此服务器将向所有客户端发送命令,客户端将询问服务器他想在哪个 ID 上执行命令,如果它是“5”,则该客户端将执行并将数据发送到服务器)。 客户端有很多命令,但为了创建具有相同错误的最小代码,我只使用了 1 个命令(dir)。基本上,服务器将命令发送给客户端,如果它与客户端当前 ID 和服务器当前 ID 匹配,它将处理该命令。默认情况下,服务器的当前 ID 是 10。以下是帮助想要回答的人的命令列表:

服务器命令:

  • 列表(显示所有连接的用户 ID 和服务器的当前 ID)--> 发生在服务器上

  • dir (request client to send its dir listing) --> 客户端发送,服务端读取

  • set(将服务器的当前 id 设置为任意数字)(例如:'set 4')

客户:

using System;
using System.Speech.Synthesis;
using System.Windows.Forms;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
namespace clientControl
{
    class Program
    {
        public static string directory = @"C:\";
        public static int id = -10;
        public static Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        static void Main(string[] args)
        {
            Connect();
            getSession();
            ReadResponse(sck);
        }
        static byte[] readResponseFunc()
        {
            long fileSize = 0;
            string fileSizeInString = null;
            byte[] fileSizeInByteArray = new byte[1024];
            int fileSizeLength = sck.Receive(fileSizeInByteArray);
            for (int i = 0; i < fileSizeLength; i++)
            {
                fileSizeInString = fileSizeInString + (char)fileSizeInByteArray[i];
            }
            try
            {
                fileSize = Convert.ToInt64(fileSizeInString);
            }
            catch { Console.WriteLine(fileSizeInString); }
            sck.Send(Encoding.ASCII.GetBytes("a"));

            byte[] responseUnknown = new byte[1];
            sck.Receive(responseUnknown);
            if (Encoding.ASCII.GetString(responseUnknown) == "b")
            {
                byte[] dataInByteArray = new byte[fileSize];
                int dataLength = sck.Receive(dataInByteArray);
                return dataInByteArray;
            }
            return Encoding.ASCII.GetBytes("ERROR RESPONSE FUNC");
        }
        static void getSession()
        {
            byte[] message_1 = Encoding.ASCII.GetBytes("make_id");
            sck.Send(Encoding.ASCII.GetBytes(message_1.Length.ToString()));
            byte[] responseUnknown = new byte[1];
            if (Encoding.ASCII.GetString(responseUnknown) == "a")
            {
                sck.Send(Encoding.ASCII.GetBytes("b"));
                sck.Send(message_1);
            }
            byte[] receivedID = readResponseFunc();
            id = Convert.ToInt32(Encoding.ASCII.GetString(receivedID));
        }
        static bool SocketConnected(Socket s)
        {
            bool part1 = s.Poll(1000, SelectMode.SelectRead);
            bool part2 = (s.Available == 0);
            if (part1 && part2)
                return false;
            else
                return true;
        }
        static void ReadResponse(Socket sck)
        {
            while (true)
            {

                if (SocketConnected(sck) == true)
                {
                    try
                    {
                        string response = Encoding.ASCII.GetString(readResponseFunc());

                        byte[] message_1 = Encoding.ASCII.GetBytes("get_id");
                        sck.Send(Encoding.ASCII.GetBytes(message_1.Length.ToString()));
                        byte[] responseUnknown = new byte[1];
                        if (Encoding.ASCII.GetString(responseUnknown) == "a")
                        {
                            sck.Send(Encoding.ASCII.GetBytes("b"));
                            sck.Send(message_1);
                        }
                        byte[] response_2InByteArray = readResponseFunc();
                        string response_2 = Encoding.ASCII.GetString(response_2InByteArray);
                        if (Convert.ToInt32(response_2) == id)
                        {
                            if (response == "dir")
                            {
                                string resultOfDirring = "Current Directory: " + directory + "\n\n";
                                string[] folderListingArray = Directory.GetDirectories(directory);
                                foreach (string dir in folderListingArray)
                                {
                                    string formed = "DIRECTORY: " + Path.GetFileName(dir);
                                    resultOfDirring = resultOfDirring + formed + Environment.NewLine;
                                }
                                string[] fileListingArray = Directory.GetFiles(directory);
                                foreach (var file in fileListingArray)
                                {
                                    FileInfo fileInfo = new FileInfo(file);
                                    string formed = "FILE: " + Path.GetFileName(file) + " - FILE SIZE: " + fileInfo.Length + " BYTES";
                                    resultOfDirring = resultOfDirring + formed + Environment.NewLine;
                                }
                                byte[] message_11 = Encoding.ASCII.GetBytes(resultOfDirring);
                                sck.Send(Encoding.ASCII.GetBytes(message_11.Length.ToString()));
                                byte[] responseUnknown_11 = new byte[1];
                                if (Encoding.ASCII.GetString(responseUnknown_11) == "a")
                                {
                                    sck.Send(Encoding.ASCII.GetBytes("b"));
                                    sck.Send(message_11);
                                }
                            }
                        }
                        else { }
                    }
                    catch { if (SocketConnected(sck) == false) { Console.WriteLine("Client Disconnected: " + sck.RemoteEndPoint); break; }; }
                }
                else if (SocketConnected(sck) == false) { Console.WriteLine("Client Disconnected: " + sck.RemoteEndPoint); break; }
            }
        }
        static void Connect()
        {
            while (true)
            {
                try
                {
                    sck.Connect(IPAddress.Parse("127.0.0.1"), 80);
                    break;
                }
                catch { }
            }
        }
    }
}

服务器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
using System.Threading;

namespace serverControl
{
    class Program
    {
        public static int ftpNum = 1;
        public static List<int> listOfClient = new List<int>();
        public static TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);
        public static string message = null;
        public static int id = 0;
        public static int selected_id = 10;
        static void Main(string[] args)
        {
            server.Start();
            Thread startHandlingClientThread = new Thread(startHandlingClient);
            startHandlingClientThread.Start();
            while (true)
            {
                Console.Write(":> ");
                string rawmessage = Console.ReadLine();
                if (rawmessage == "list")
                {
                    Console.WriteLine("SELECTED ID: " + selected_id);
                    Console.WriteLine("List of Clients ID:");
                    for (int i = 0; i < listOfClient.Count; i++)
                    {
                        Console.WriteLine(listOfClient[i]);
                    }
                    message = rawmessage+"PREVENT_REPETITION_IN_COMMAND";
                }
                else if (rawmessage.Contains("set ")) { int wantedChangeId = Convert.ToInt32(rawmessage.Replace("set ", "")); selected_id = wantedChangeId; message = rawmessage+ "PREVENT_REPETITION_IN_COMMAND"; }
                else
                {
                    message = rawmessage;
                }
            }
        }

        static byte[] readResponseFunc(Socket sck)
        {
            long fileSize = 0;
            string fileSizeInString = null;
            byte[] fileSizeInByteArray = new byte[1024];
            int fileSizeLength = sck.Receive(fileSizeInByteArray);
            for (int i = 0; i < fileSizeLength; i++)
            {
                fileSizeInString = fileSizeInString + (char)fileSizeInByteArray[i];
            }
            fileSize = Convert.ToInt64(fileSizeInString);

            sck.Send(Encoding.ASCII.GetBytes("a"));

            byte[] responseUnknown = new byte[1];
            sck.Receive(responseUnknown);
            if (Encoding.ASCII.GetString(responseUnknown) == "b")
            {
                byte[] dataInByteArray = new byte[fileSize];
                int dataLength = sck.Receive(dataInByteArray);
                return dataInByteArray;
            }
            return Encoding.ASCII.GetBytes("ERROR RESPONSE FUNC");
        }
        static void startHandlingClient()
        {
            while (true)
            {
                handleClient(server);
            }
        }
        static void handleClient(TcpListener clientToAccept)
        {
            Socket sck = clientToAccept.AcceptSocket();
            Thread myNewThread = new Thread(() => ReadResponse(sck));
            myNewThread.Start();
        }
            static bool SocketConnected(Socket s)
            {
                bool part1 = s.Poll(1000, SelectMode.SelectRead);
                bool part2 = (s.Available == 0);
                if (part1 && part2)
                    return false;
                else
                    return true;
            }
        static void ReadResponse(Socket sck)
        {
            Thread myNewThread = new Thread(() => SendtoClient(sck));
            myNewThread.Start();
            Thread.Sleep(2000);
            while (true)
            {

                if (SocketConnected(sck) == true)
                {
                    try
                    {
                        byte[] dataInByteArray = readResponseFunc(sck);

                        string response = Encoding.ASCII.GetString(dataInByteArray);
                        Console.WriteLine("res: " + response);
                        if (response != "make_id" && response != "get_id") { Console.WriteLine(response); }
                        if (response == "make_id")
                        {
                            Console.WriteLine("Someone wants an ID");
                            byte[] message_1 = Encoding.ASCII.GetBytes(id.ToString());
                            listOfClient.Add(id);
                            // START
                            sck.Send(Encoding.ASCII.GetBytes(message_1.Length.ToString()));
                            byte[] responseUnknown = new byte[1];
                            if (Encoding.ASCII.GetString(responseUnknown) == "a")
                            {
                                sck.Send(Encoding.ASCII.GetBytes("b"));
                                sck.Send(message_1);
                            }
                            id++;
                        }
                        if (response == "get_id")
                        {
                            byte[] message_1 = Encoding.ASCII.GetBytes(selected_id.ToString());
                            sck.Send(Encoding.ASCII.GetBytes(message_1.Length.ToString()));
                            byte[] responseUnknown = new byte[1];
                            if (Encoding.ASCII.GetString(responseUnknown) == "a")
                            {
                                sck.Send(Encoding.ASCII.GetBytes("b"));
                                sck.Send(message_1);
                            }
                        }
                    }
                    catch { if (SocketConnected(sck) == false) { Console.WriteLine("Client Disconnected: " + sck.RemoteEndPoint); break; }; }
                }
                else if (SocketConnected(sck) == false) { Console.WriteLine("Client Disconnected: " + sck.RemoteEndPoint); break; }
            }
        }
        static void SendtoClient(Socket sck)
        {
            string tempmessage = null;
            while (true)
            {
                if (SocketConnected(sck) == true)
                {
                    if (tempmessage != message)
                    {
                        if (!message.Contains("PREVENT_REPETITION_IN_COMMAND"))
                        {
                            byte[] message_1 = Encoding.ASCII.GetBytes(message);
                            sck.Send(Encoding.ASCII.GetBytes(message_1.Length.ToString()));
                            byte[] responseUnknown = new byte[1];
                            if (Encoding.ASCII.GetString(responseUnknown) == "a")
                            {
                                sck.Send(Encoding.ASCII.GetBytes("b"));
                                sck.Send(message_1);
                            }
                        }
                        tempmessage = message;
                    }
                }
                else if (SocketConnected(sck) == false)
                { Console.WriteLine("Client Disconnected: " + sck.RemoteEndPoint); break; }
            }
        }
    }   
}

问题: 问题出在 GetSession 或 ReadResponseFunc 函数中。客户端认为服务器收到的他的 ID 是“a”(它应该是一个整数)。我不想要一个建议我使用其他库或 TcpClient 类

赏金:

我会悬赏给解决问题的人,没有过期时间。

最佳答案

你的代码逻辑很困惑。我的问题是:为什么要在服务器和客户端之间来回发送“a”和“b”?是否确认已收到消息?

无论如何,通过我刚才所做的快速测试,问题似乎出在您的服务器的第 59 行:

sck.Send(Encoding.ASCII.GetBytes("a"));

这是我在测试过程中发现的:

  1. 服务器执行。
  2. 客户端执行。
  3. 客户端向服务器发送“make_id”的长度(客户端第51行)
  4. 客户端等待响应返回。
  5. 服务器读取值并发回'a'(服务器第59行)

您可能需要花一些时间理顺您的协议(protocol),以减少困惑并更有条理。这会帮助像我这样的人更容易地发现错误。

关于C# 套接字 : Client Mishandle 'a' as the Client's id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43589889/

有关C# 套接字 : Client Mishandle 'a' as the Client's id的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  3. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  4. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  5. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  6. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  7. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  8. 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

  9. ruby-on-rails - Rails 中的 NoMethodError::MailersController#preview undefined method `activation_token=' for nil:NilClass - 2

    似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai

  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

随机推荐