0

私はどうしても助けが必要です。私は基本的に、暗号化を使用してメッセージを送受信するプログラムを作成しました。暗号化の部分は正常に機能していますが、私はスレッドにかなり慣れていないため、アプリケーションのクライアント/サーバー部分を一生並べることができません。チャットプログラムはTCPを使用した直接IP接続であるため、各ホストはクライアントとサーバーです。デバッグ時に発生していると思われる問題は、クライアントがサーバースレッドに接続しようとしたときにサーバースレッドの準備ができていないか、準備ができている場合はスレッドを放棄しないため、クライアントが接続できることです。私はこれに何時間も取り組んできました、そしてそれは非常にイライラします..誰かが助けてくれることを願っています!以下に私のコードを含めました。これは、メインフォームからのコードスニペットであり、クライアントとサーバーの側面を構成します。

private void InitializeComponent() {

        server = new ServerSide("127.0.0.1",7865);
        servThread = new Thread(new ThreadStart(server.begin));
        client = new ClientSide("127.0.0.1",7865);
        clientThread = new Thread(new ThreadStart(client.begin));
        servThread.Start();
        clientThread.Start();


        //servThread.Join();
        //clientThread.Join();

}

これは私のServerSideコードです:

public class ServerSide
{
    String IpString;
    int tcpPort;
    bool goodToGo = false;
    System.Net.IPAddress ipAddress = null;
    public ServerSide(String ip, int tcpPort)
    {
        IpString = ip;
        bool isValidIp = System.Net.IPAddress.TryParse(IpString, out ipAddress);
        if (isValidIp == true) // check if the IP is valid, set the bool to true if so
        {
            goodToGo = true;
        }
        else
        {
            goodToGo = false;
        }
    }

    public void begin()
    {
        try
        {
            IPAddress ipAd = IPAddress.Parse(IpString);

            /* Initializes the Listener */
            TcpListener myList = new TcpListener(ipAd, tcpPort);
            Socket s = null;
            /* Start Listening at the specified port */
            while (true)
            {
                myList.Start();

                if (myList.Pending())
                { 
                        s = myList.AcceptSocket();
                         break;
                }

            }

            String toReceive = "";
                    while (true)
                    {
                        byte[] b = new byte[4096];
                        int k = s.Receive(b);
                        for (int i = 0; i < k; i++)
                            toReceive += Convert.ToString((Convert.ToChar(b[i])));

                        // ASCIIEncoding asen = new ASCIIEncoding();

                        var form = MainForm.ActiveForm as MainForm;
                        if (form != null)
                        {
                            form.messageReceived(toReceive);
                        }
                        toReceive = "";
                    }
                }
        catch (Exception e)
        {
            Console.WriteLine("Error..... " + e.StackTrace);
        }
    }
}

}

ClientSideコード:

 public class ClientSide
{
    private String IpString;
    private int tcpPort;
    private TcpClient tcpInt;
    private static Stream stm;
    private System.Net.IPAddress ipAddress = null;
    private bool goodToGo = false;

    public ClientSide(String ip, int tcpPort)
    {

        IpString = ip;
        this.tcpPort = tcpPort;

        bool isValidIp = System.Net.IPAddress.TryParse(IpString, out ipAddress);
        if (isValidIp == true)
        {
            goodToGo = true;
        }
        else
        {
            goodToGo = false;
        }
    }

    public void begin()
    {
        try
        {
            tcpInt = new TcpClient();
            // Console.WriteLine("Connecting.....");



            tcpInt.Connect(IpString, tcpPort);
            // use the ipaddress as in the server program

            // Console.WriteLine("Connected");

            // String str = Console.ReadLine();
            stm = tcpInt.GetStream();
        }

        catch (Exception e)
        {
            Console.WriteLine("Error..... " + e.StackTrace);
        }
    }


    public void sendMessage(String str)
    {
      //  stm = tcpInt.GetStream();

        ASCIIEncoding asen = new ASCIIEncoding();
        byte[] ba = asen.GetBytes(str);

        stm.Write(ba, 0, ba.Length);

      /**  byte[] bb = new byte[100];
        int k = stm.Read(bb, 0, 100);

        for (int i = 0; i < k; i++)
            Console.Write(Convert.ToChar(bb[i]));*/

    }
}

}

繰り返しになりますが、通常発生するのは、ホストが接続をアクティブに拒否したというエラーをクライアントが受信することです。しかし、タイミングを設定する方法がわかりません。サーバーでTCP接続をリッスンする方法を探していますが、他のスレッドに移動してTCP接続を作成し、サーバーを送信する方法を探しています(現在、ローカルホストでこれをテストしています)。ありがとう。

4

1 に答える 1

7

クラスのコンストラクターで、メンバーServerSideを初期化するのを忘れました。tcpPort忘れたため、サーバーはポート0をリッスンしようとし、クライアントはポート7865に接続しようとしますが、失敗します。

ServerSideこのコードをクラスのコンストラクターに追加してみてください。

this.tcpPort = tcpPort;

スレッドに関しては、サーバースレッドがリッスンを開始する前にクライアントスレッドが接続しようとすると、問題が発生する可能性があります。ループを使用して、接続を何度も試行し(たとえば、10回)、成功しなかった場合はタイムアウト(たとえば、1秒)を使用できます。このようにして、10回再試行し、その後あきらめます。

于 2012-04-18T06:54:26.277 に答える