0

以前にも同じような質問をしましたが、それを行う方法が見つからないようです。一部のデータが失われ、一部のデータが最後のメッセージの一部として送信される可能性があるため、TCPを介したデータの送信に問題があることを理解しています。リストから一連のコマンドを送信しているので、それらを修正しようとしています。

送信するためのクライアントのコードは次のとおりです。

private void sendBtn_Click(object sender, EventArgs e)
        {
            try
            {
                for (int i = 0; i < listORequestedCommands.Items.Count; i++)
                {
                    clientSock.Send(Encoding.Default.GetBytes(listORequestedCommands.Items[i].ToString()), listORequestedCommands.Items[i].ToString().Length, SocketFlags.None);
                }
                removeAll_Click(sender, e);
                sendBtn.Enabled = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error!");
                this.Close();
            }

        }

受信用のサーバーコードは次のとおりです。

private void clientReceived(Client sender, byte[] data)
        {
            try
            {
                Invoke((MethodInvoker)delegate
                {
                    for (int i = 0; i < lstClients.Items.Count; i++)
                    {
                        Client client = lstClients.Items[i].Tag as Client;

                        if (client.ID == sender.ID)
                        {
                            string incommingCommand = Encoding.Default.GetString(data);
                            if (incommingCommand.CompareTo("") != 0)
                            {
                                lstClients.Items[i].SubItems[1].Text = incommingCommand;
                                string[] splittedIncommingCommand = incommingCommand.Split(' ');

                                int numRunProc = 0;

                                do
                                {
                                    numRunProc = countProcesses();
                                }
                                while ((numRunProc >= maxProcesses) || (numRunProc + Int32.Parse(splittedIncommingCommand[splittedIncommingCommand.Length - 1]) >= maxProcesses));

                                Process processToRun = new Process();
                                processToRun.StartInfo.FileName = splittedIncommingCommand[0];
                                processToRun.StartInfo.WorkingDirectory = Path.GetDirectoryName(splittedIncommingCommand[0]);
                                processToRun.StartInfo.Arguments = "";

                                for (int j = 1; j < splittedIncommingCommand.Length; j++)
                                {
                                    processToRun.StartInfo.Arguments += " " + splittedIncommingCommand[j];
                                }

                                processToRun.Start();
                            }
                            break;
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error!");
                this.Close();
            }

        }

サイズプレフィックスとシリアル化で何かをするように指示されましたが、問題が発生し、それを機能させることができないようです。

4

2 に答える 2

0

サイズプレフィックスとシリアル化の正確な意味はわかりませんが、サーバーにクライアントから期待されるバイト数を通知するか、メッセージの最後を何らかの方法で「マーク」することをお勧めします(つまり、文字列)。 2つのCRLF、または<eom>や<!-メッセージの終わり->などの疑似タグ/コメントが続きます。最初のオプションでは、通常、バイナリデータを使用する必要があります。2つ目は、サンプルコードの方が簡単なようです。

于 2013-02-03T14:29:04.720 に答える
0

ご要望に応じて、ネットワークライブラリnetworkcomms.netを使用して実用的なソリューションを提供できます。以下のコード例は、単一の文字列を送信します。サーバーセクションを変更することで、使用するなどstring[]に簡単に変更できますList<string>

NetworkComms.AppendGlobalIncomingPacketHandler<string>

NetworkComms.AppendGlobalIncomingPacketHandler<string[]>

また

NetworkComms.AppendGlobalIncomingPacketHandler<List<string>>

送信する内容に関係なく、クライアント側は変更されません。サーバーのコードは次のようになります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NetworkCommsDotNet;

namespace TCPServer
{
    class Program
    {
        static void Main(string[] args)
        {
            NetworkComms.AppendGlobalIncomingPacketHandler<string>("Message", (packetHeader, connection, incomingString) => 
            {
                    Console.WriteLine("The server received a string - " + incomingString);
                    //Perform any other operations on the string you want to here.
            });

            TCPConnection.StartListening(true);

            Console.WriteLine("Server ready. Press any key to shutdown server.");
            Console.ReadKey(true);
            NetworkComms.Shutdown();
        }
    }
}

そしてクライアントのために:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NetworkCommsDotNet;

namespace TCPClient
{
    class Program
    {
        static void Main(string[] args)
        {
            string messageToSend = "This is the message to send";
            TCPConnection.GetConnection(new ConnectionInfo("127.0.0.1", 10000)).SendObject("Message", messageToSend);

            Console.WriteLine("Press any key to exit client.");
            Console.ReadKey(true);
            NetworkComms.Shutdown();
        }
    }
}

明らかに、WebサイトからNetworkCommsDotNet DLLをダウンロードして、「usingNetworkCommsDotNet」リファレンスに追加できるようにする必要があります。また、クライアントの例のサーバーIPアドレスは現在「127.0.0.1」です。これは、サーバーとクライアントの両方を同じマシンで実行している場合に機能するはずです。詳細については、入門書またはクライアントサーバーアプリケーションの作成方法に関する記事も確認してください。

于 2013-02-03T15:18:11.360 に答える