2

接続のIPアドレスを取得して、以前に接続したことがあるかどうかを確認する必要があります(以前に接続したことがあるが、もう接続されていない場合は、IPのリストと照合して、オフラインと表示されます)。(ノンブロッキングソケットを使用)

最初に受け入れずに IP を取得するにはどうすればよいですか。

///

    case FD_ACCEPT:
        int W;
        for(W = 0;W <= ListView_GetItemCount(GetDlgItem(HwND,IDC_IPLIST));W++){

それで、リストビューに対してIPをチェックして、以前に接続したことがあるかどうかを確認します. ある場合は、前回使用していたのと同じソケット番号を使用したいと思います。

これが私が今接続を受け入れる方法です

        case FD_ACCEPT: 
        while(Client[F] != NULL)
        {
        F++;
        }
        Client[F]=accept(wParam,(LPSOCKADDR)&ServAdr,&AdrLen);
        break;

だから分解して…

以前の接続の IP リストに対して着信接続を確認したいと考えています。このリストには、IP とそのオンライン/オフライン (接続済み/未接続) が含まれます。新しい接続を受け入れたときにオンラインと表示する前に接続した場合、新しい接続をすべて一緒に使用するのではなく、前回使用したのと同じソケット番号を使用します。そうでない場合は、リストに追加したいと思います。(リストにはソケット番号が含まれます)

これがあまり意味をなさない場合は、もう少し明確にしようとします。

4

4 に答える 4

2

あなたが求めていることは、 ではできませんaccept()SOCKET接続が受け入れられ、新しいハンドルが割り当てられるまで、接続の情報にアクセスすることはできません。接続情報を事前に取得するには、WSAAccept()代わりに のコールバック機能を使用する必要があります。

SOCKETいずれにせよ、既存のハンドルを新しい接続に再利用する方法はありません。受け入れられた各接続には、独自の一意のSOCKETハンドルが必要です。ただし、以前に見た IP からの新しい接続を ListView の既存のスロットに関連付けることはできます。

于 2012-04-22T04:07:33.663 に答える
1

あなたが望むものを達成することが可能であるか、効率的な仕様であるかはわかりません。私は次のいずれかを行います:

  1. すべての接続を受け入れてから IP アドレスを確認し、リストにない接続を切断します

  2. (これはおそらくあなたには適していません) 許可された IP アドレスのみが通過できるように、上流のファイアウォールを構成します。

于 2012-04-22T01:37:49.167 に答える
1

ソケット番号が によって返される番号を意味する場合、そのaccept()値にまったく依存することはできません。つまり、リモート ホストが切断されて再度接続された場合、返される値はaccept()おそらく異なるものになるでしょう。この数字に頼るのは意味がありません。

ソケット番号で配列内の位置を意味する場合は、返された値をaccept()一時変数に割り当てることができます。

SOCKET tmpSock;
sockaddr_in tmpAddr;
int namelen;
typedef struct { /*...*/ } TClient;
TClient Client[MAX_CLIENTS];
/*...*/
tmpSock = accept(/*...*/);
namelen = sizeof(tmpAddr);
getpeername(tmpSock, (sockaddr*)&tmpAddr,&namelen);
/*...*/
//looking for tmpAddr.sin_addr in your list and calculating
//the list position - F
/*...*/
Client[F].Socket = tmpSock;
Client[F].IsConnected = true;
Client[F].Address = tmpAddr.sin_addr;

呼び出し後listen()、OS カーネルは、ユーザーが設定したポート/ローカル IP へのすべての着信接続を受け入れることに注意してください。これは、connect()呼び出してもしなくても、リモート ホストの が正常に返されることを意味しaccept()ます (リッスン キューにスペースがある場合)。を呼び出すaccept()と、ソケットとの対話のみが許可されます。リモート ホストから見た接続状態は変更されません。

于 2012-04-22T03:54:23.717 に答える
0

ワイルドカード アドレス ( ) にバインドする場合INADDR_ANY、通信に使用される IP アドレスは、接続が来るまで決定されません (パケットが通過するインターフェイスからのものになります)。同じリッスン ソケットにより、複数の IP アドレスで接続が受け入れられる場合があります。

特定のアドレスにバインドする場合、バインド先のアドレスは既にわかっています。

于 2012-04-22T05:25:20.117 に答える