2012-01-11 14 views
1

私は以下のようにしています。サーバーがListenするためのソケットが作成されているコンストラクタを開始します。 (バインディング、リスニングなど) 次に、クライアントからの着信コールを受け付ける必要がある着信コールを検索する関数を開始するThreadを生成します。 接続したソケットをリストに入れる必要があります。 その後、新しいスレッドが作成されています。C++スレッド/ベクトルチャット

しかし、彼はクライアントの受け入れに立ち往生し、私は本当にそれを調べました。 たくさんお願いします。

First-chance exception at 0x010820b1 in ChatServer.exe: 0xC0000005: Access violation reading location 0x00000000. Unhandled exception at 0x010820b1 in ChatServer.exe: 0xC0000005: Access violation reading location 0x00000000.

それはmuch-ビットです> ServerCode:

int main(int argc, char* argv[]) 
{ 

//Constructor that takes care of making connection 

//Throw in a new Thread 

CreateThread(0,0,&ServerListenThread,0,0,0); 

//while loop to get input and pass it to the SendMessages function 

//function being called within a Thread 

DWORD WINAPI ServerListenThread(LPVOID pParam) 
{ 
    while(1) 

     CServerObj->StartListenClient(); 
    return 0; 
} 

void CServer::StartListenClient() 
{ 

    sockaddr_in i_addr; 
    int i_addrlen = sizeof(i_addr); 
    SocketC = accept(SocketS,(struct sockaddr*)&i_addr,&i_addrlen); <<<Here it gives the Access Violation< at the accept 
    { 
      cout << "A Connection was found with :" <<endl; 
    } 

    SocketS = SocketC; 

    if(SocketS != INVALID_SOCKET) 
    { 
     vClientList.push_back(SocketS); 
     CreateThread(0,0,&ServerRecThread, (void*)SocketS, 0,0); 
    } 
} 
+0

デバッグモードでコールスタックを確認して、ここにポストできますか? _Insideが失敗したという情報を投稿しただけですが、この_Insideと呼ばれるコードのどの部分が面白いですか。 – Zuljin

+0

CServer :: SendMessagesのforループの終了条件が原因である可能性があります。itl!= vClientVector.end()を使用すると、より小さい演算子がここで予測できない結果を生成しています。 – Jack

答えて

1

あなたが最も可能性の高いあなたが古いイテレータを通して、あなたのベクトルの値にアクセスしようとしているシナリオに実行されています。あなたがスレッドを使用しているので、あるスレッドがベクトルに追加し、そのベクトルの内容の再割り当てを引き起こしたシナリオがあるかもしれません。したがって、別のスレッドが同時にベクトルを反復している場合は、元のベクトルの内容を再割り当てした後にその反復子が無効になり、反復子が存在しないコンテンツを指しているところでエラーが発生しますベクトルの内側。

もしあなたのvClientVectorがスレッド間で共有されていて、他のスレッドがそれを読んでいる間にそれに書き込まれているスレッドがあれば、おそらくは複数の読者ができるように、おそらくリーダ/一度に1人のライターしかいない。

+0

私はあなたを正しく理解していれば、私はそれをミューテックスで保護する必要があります。 しかし、問題は、1つのクライアントが接続されていてもハングアップすることです。 したがって、もし私が接続すると、 '_Ptr'(デバッグ)に格納される必要があるsock_identifierである128の値があることがわかります。ベクトルは空であり、そのままです。 –

+0

あなたが投稿したコードは非常に混乱しています...私は '_Inside'がどこから呼び出されているのか分かりませんので、私はこのエラーを作成していることについて教訓を得ています。一般に、ifあなたは共有リソースを持っており、あなたはそのリソースを読み書きしていますので、保護する必要があります。ところで、スレッドを作成すると、自動的に2つのスレッド、つまり親スレッドと生成された「子」スレッドがあります。つまり、私はあなたのスレッドがお互いにやりとりする方法について、まだ少し混乱しています。 – Jason

+0

サーバが新しい接続要求を受け付けた後も、接続されているソケットをベクターに入れます。その後、スレッドを作成するためにSocketを渡します。そのスレッドはperticulairクライアントからのデータを受け取るだけです。 そのデータは、ベクトルを保持する別の関数 'int CServer :: SendMessages(string sBuf)'に転送されています(接続されたソケットを使って。 –