2010-11-30 6 views
2

後にソケットを再び聴きます。実際に私は2つのサーバーとクライアントを持っています。スタートは、私は小さなC#のソケットアプリケーションを書いて切断

ユーザーは、クライアントを実行するサーバーのIPとポートを入力し、印刷機「接続」、その後、一度、彼らはテキストボックスにテキストを入力し、それをサーバーに送信することができます接続されています。 、最も最近受信したメッセージの下に:

サーバは単に「未接続」または「[ポート] [IP]からの接続」のいずれかが表示されません。

サーバーが正常にメッセージを受け取り、さらにはクライアントの切断罰金を処理します。 クライアントが切断された後にもう一度聞き取ろうとしていますが、何らかの理由で試してみると何も聞こえなくなります。ここで

は、私のコードの一部です:

Socket socket; 
    private void listen() 
    { 
     socket = new Socket(AddressFamily.InterNetwork, 
      SocketType.Stream, ProtocolType.Tcp); 
     socket.Bind(new IPEndPoint(IPAddress.Any, 12345)); 
     socket.Listen(10); 
     socket.BeginAccept(new AsyncCallback(acceptAsync), socket); 
    } 

private void receiveAsync(IAsyncResult res) 
    { 
     Socket socket = (Socket)res.AsyncState; 

     try 
     { 
      int nBytes = socket.EndReceive(res); 
      if (nBytes > 0) 
      { 
       Invoke(new MethodInvoker(delegate() 
       { 
        lMessage.Text = encoder.GetString(buffer); 
       })); 
       setupReceiveAsync(socket); 
      } 
      else 
      { 
       Invoke(new MethodInvoker(delegate() 
       { 
        lConnections.Text = "No Connections."; 
        lMessage.Text = "No Messages."; 
        socket.Shutdown(SocketShutdown.Both); 
        socket.Close(); 
        listen(); 
       })); 
      } 
     } 
     catch { } 
    } 

最後の行:聞きます();エラーを投げるものです。 私は単にsocket.BeginAccept()をもう一度呼び出そうとしましたが、例外もスローされます。

私は取得していたメッセージがある:私は私の聞いて呼び出していない場合は、各ソケットアドレス(プロトコル/ネットワークアドレス/ポート)の

つだけ使用量は、通常、

を許可されています()関数を呼び出して、代わりにsocket.BeginAccept()を呼び出すと、最初にsocket.listen()を呼び出す必要があります。

socket.listen関数を呼び出すと、既に接続されていることがわかりますカート開始聴き取り

私はその後、私は再び受信を開始しますか、非同期接続を行い、いくつかの非同期メッセージを受け取ったら?

+0

コードをさらに投稿してください。リスニングソケットを適切に廃棄せずに放棄しているように聞こえますが、まだガベージコレクションされていないので、ポートはまだ開いています。 – cdhowie

+0

どこで 'EndAccept'を呼び出していますか? – Donnie

答えて

2

socketsocket変数には、listen()を2度目に呼び出したときに、リスニングソケットが既に割り当てられています。そのため、1つの使用が許可されていることがわかります。繰り返す必要があるのは、socket.BeginAccept(new AsyncCallback(acceptAsync), socket)コールだけです。だからreceiveAsync(...)メソッド内のlisten()へのコールをsocket.BeginAccept(new AsyncCallback(acceptAsync), socket)に置き換えてみてください。

+0

は私の問題を解決しました。 – msuhash

2

非同期Begin*は、常にEnd*が続きます。 Asynchronous Server Socketの使用を参照してください。あなたのacceptメソッドのようなものでなければなりません:

try { 
     listener.Bind(localEP); 
     listener.Listen(10); 

     while (true) { 
      allDone.Reset(); 

      Console.WriteLine("Waiting for a connection..."); 
      listener.BeginAccept(
       new AsyncCallback(SocketListener.acceptCallback), 
       listener); 

      allDone.WaitOne(); 
     } 
    } catch (Exception e) { 

サーバーを意味し、その指定されたポート/ IPでリッスンアプリ。通常、リスニングモードではは常にです。これがサーバーと呼ばれる理由です。それは切断クライアントを接続しますが、リスニングモードに常にあることができます。

これは、サーバがクライアントの接続を切断すると、でも、 - リスニングモードになっていることを意味します。着信接続も受け入れることができます。

ただし、切断要求はクライアントから送信される場合もありますが、サーバーによって強制的に適用される場合もあります。

サーバのプロセスは、次のとおりです。へ

  1. 接続:ソケットへ

    1. バインドが
    2. が接続

    クライアントのプロセスがあるを受け入れる聞きますサーバー

  2. 送信/受信メッセージ

いくつか入ってくるクライアントを処理するためのサーバーのための方法、夫婦、次のようにあります。

  • は、着信接続がList<TcpClient>内のインスタンスのために、リスト内に維持されています。
  • 着信クライアントを処理する1つの方法はスレッドによるものです。たとえば、受信クライアントごとに、サーバーとクライアント間の通信を処理するスレッドを生成します。例えば、checkout this example。クライアント通信(TX/RX)を管理するためのスイッチング

_

private void ListenForClients() 
{ 
    this.tcpListener.Start(); 

    while (true) 
    { 
    //blocks until a client has connected to the server 
    TcpClient client = this.tcpListener.AcceptTcpClient(); 

    //create a thread to handle communication 
    //with connected client 
    Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm)); 
    clientThread.Start(client); 
    } 
} 
  • 使用シングルスレッドおよび使用状況。
関連する問題