C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: MFC ソケット通信 接続が不安定


(過去ログ 91 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■53983 / inTopicNo.1)  MFC ソケット通信 接続が不安定
  
□投稿者/ ホエホエ (16回)-(2010/10/01(Fri) 14:20:57)

分類:[C/C++] 

いつもお世話になっております。

タイトルにもありますがVC++6.0MFCにてCSocketクラスの派生で
TCPクライアント側クラスを作り、それでソケット通信プログラムを
作成しているのですが、サーバー側(既製のFA装置)と接続ができたり、
失敗したりしてしまいます。現象としては…

・初回はほぼ確実に接続できる。しかし切断&プログラム終了後に
 再度プログラム開始&接続しようとすると失敗する。
 pingコマンドは問題なく成功。

・上記の状態はしばらく(5〜8分程度)待つと再接続できる。

・LANコネクタが1つのパソコンの場合、CSocketクラスで
 引数なし(ローカルIP指定せず)でCreateメソッドを
 実行後にConnect(接続処理)をすると確実に成功する。

・LANコネクタが複数のパソコンの場合はローカルIPを指定しないと
 Createメソッド実行後にConnect(接続処理)が失敗してしまう。


====ソースプログラム(接続部のみ抜粋)=====
//LPCTSTR p_pszLocalAddress :ローカルIPアドレス(自機側使用LANコネクタ設定値)
//LPCTSTR p_pszConectAddress :ホストIPアドレス(接続先)
//UINT p_nPortNo :通信ポート番号
//
BOOL CClientSocket::OpenClient( LPCTSTR p_pszLocalAddress, LPCTSTR p_pszConectAddress, UINT p_nPortNo )
{
CString strSocketAddress= _TEXT("");
UINT nSocketPort = 0;
BOOL bRet = GetSockName( strSocketAddress, nSocketPort ) && !strSocketAddress.IsEmpty() && nSocketPort != 0;

//接続中?
if( !bRet )
{
//生成&接続
bRet = Create( p_nPortNo, SOCK_STREAM, p_pszLocalAddress ) && Connect( p_pszConectAddress, p_nPortNo );
}
return bRet;
}

OSはWindowsXPです。

上記で何かマズい処理であれば教えてください。

または複数LANコネクタを持ったパソコンでTCPクライアントソケット通信が
できるのであれば、ローカルIPを指定するのは特に拘っておりませんので、
他に何か良い方法があれば教えてください。
引用返信 編集キー/
■54006 / inTopicNo.2)  Re[1]: MFC ソケット通信 接続が不安定
□投稿者/ れい (960回)-(2010/10/02(Sat) 04:13:27)
No53983 (ホエホエ さん) に返信
> タイトルにもありますがVC++6.0MFCにてCSocketクラスの派生で
> TCPクライアント側クラスを作り、それでソケット通信プログラムを
> 作成しているのですが、サーバー側(既製のFA装置)と接続ができたり、
> 失敗したりしてしまいます。現象としては…
>
> ・初回はほぼ確実に接続できる。しかし切断&プログラム終了後に
>  再度プログラム開始&接続しようとすると失敗する。
>  pingコマンドは問題なく成功。
>
> ・上記の状態はしばらく(5〜8分程度)待つと再接続できる。

あくまで勘ですが、
ソケットの終了をきちんと行っていないのだろうと思います。
サーバー側が接続切断を認識できず、次のデータを待っているのでしょう。

正しく終了用のコマンドを送っているか、
行儀よく切断しているかを確認するとよいかと思います。

> ・LANコネクタが1つのパソコンの場合、CSocketクラスで
>  引数なし(ローカルIP指定せず)でCreateメソッドを
>  実行後にConnect(接続処理)をすると確実に成功する。
>
> ・LANコネクタが複数のパソコンの場合はローカルIPを指定しないと
>  Createメソッド実行後にConnect(接続処理)が失敗してしまう。

どのようなエラーコードが出ていますか?

> 上記で何かマズい処理であれば教えてください。

> BOOL bRet = GetSockName( strSocketAddress, nSocketPort ) && !strSocketAddress.IsEmpty() && nSocketPort != 0;
接続しているのかどうかを調べるのにいちいちGetSockNameを使うのは勿体ないし、
非同期呼び出しを使う際などに問題になります。
ローカル変数にでも状態を保存しておきましょう。

> タイトルにもありますがVC++6.0MFCにてCSocketクラスの派生で
> TCPクライアント側クラスを作り、それでソケット通信プログラムを
> 作成しているのですが、サーバー側(既製のFA装置)と接続ができたり、

いろいろと都合もあるでしょうし、反論のある方もいるかとおもいますが、
MFCのCSocketおよびCAsyncSocketには問題がたくさんあり、オススメできません。
WinSockを直接呼んだほうがよいかと思います。

引用返信 編集キー/
■54009 / inTopicNo.3)  Re[2]: MFC ソケット通信 接続が不安定
□投稿者/ ホエホエ (17回)-(2010/10/02(Sat) 10:39:00)
れいさん>
ご返信ありがとうございます。

確かにサーバー側にアプリケーション終了時にイキナリCloseで切断しています。
もしかしたらFA装置側に切断手続きを取らないといけないのかもしれません。
FA装置側マニュアルを1度確認してみようと思います。
でもLANコネクタが1つのパソコンでなら問題ないのはなぜでしょう??

googleで検索して参考にしたサイトがCSocketおよびCAsyncSocketを
使っていたしMFC標準だから安心と思ってたんですが、問題あったんですね。
ちょっと時間的な余裕がないのでWinSockに置き換えれるか微妙ですが
比較的分かり易いサイトがあれば教えてください。
引用返信 編集キー/
■54015 / inTopicNo.4)  Re[3]: MFC ソケット通信 接続が不安定
□投稿者/ れい (961回)-(2010/10/02(Sat) 15:57:56)
No54009 (ホエホエ さん) に返信
> 確かにサーバー側にアプリケーション終了時にイキナリCloseで切断しています。
> もしかしたらFA装置側に切断手続きを取らないといけないのかもしれません。
> FA装置側マニュアルを1度確認してみようと思います。
> でもLANコネクタが1つのパソコンでなら問題ないのはなぜでしょう??

LANコネクタが一つのパソコンだと2回目の接続もうまくいくのですか?
最初の質問の文章を読む限りはそうはとれませんが。

> googleで検索して参考にしたサイトがCSocketおよびCAsyncSocketを
> 使っていたしMFC標準だから安心と思ってたんですが、問題あったんですね。
> ちょっと時間的な余裕がないのでWinSockに置き換えれるか微妙ですが
> 比較的分かり易いサイトがあれば教えてください。

分かり易いかどうかは人それぞれなので自分で探すのがよいでしょう。
引用返信 編集キー/
■54025 / inTopicNo.5)  Re[4]: MFC ソケット通信 接続が不安定
□投稿者/ .SHO (1370回)-(2010/10/02(Sat) 20:53:14)
TCPの仕様です。

SO_REUSEADDR を設定すれば動くと思いますが
CSocketクラスは使用したことがないので、御自身で調べてください。

ちなみに、TCPの仕様なので WinSock にしても現象は変わりません。

引用返信 編集キー/
■54029 / inTopicNo.6)  Re[5]: MFC ソケット通信 接続が不安定
□投稿者/ れい (962回)-(2010/10/03(Sun) 04:23:02)
No54025 (.SHO さん) に返信
> TCPの仕様です。
>
> SO_REUSEADDR を設定すれば動くと思いますが

よく見たら
> bRet = Create( p_nPortNo, SOCK_STREAM, p_pszLocalAddress ) && Connect( p_pszConectAddress, p_nPortNo );
となってますね。

同じクライアント側Portで再接続しようとしているのでしょうから、.SHOさんの言うとおりTIME_WAITの問題ですね。
ですが、SO_REUSEADDRはオススメしません。
大抵はうまく動くでしょうが、パケット重複の問題が生じる場合があります。

なので、普通はクライアント側ポートは乱数を使って適当に割り当てたり、
TIME_WAITになっていない適当なポートを探して割り当てます。

> bRet = Create( 0, SOCK_STREAM, p_pszLocalAddress ) && Connect( p_pszConectAddress, p_nPortNo );
こうすればよいかと。

ちなみにSO_REUSEADDRはCAsyncSocket::SetSockOptで設定します。

NICが2個ある場合の問題は解決してませんね。
エラーコードがわからないとなんともいえないかな。
引用返信 編集キー/
■54111 / inTopicNo.7)  Re[6]: MFC ソケット通信 接続が不安定
□投稿者/ ホエホエ (18回)-(2010/10/05(Tue) 13:02:52)
.SHOさん>
れいさん>
ご両名のご忠告通りでした!!ありがとうございましたm(_ _)m

Createメソッドのポート指定の値を0にすることで、毎回接続できました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -