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

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

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

Re[6]: Winsockについて


(過去ログ 31 を表示中)

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

■14865 / inTopicNo.1)  Winsockについて
  
□投稿者/ モー (9回)-(2008/02/28(Thu) 04:13:54)

分類:[VB6 以前] 

Winxpサーバーアプリから共通のポートでVB6のdllを用い、クライアントのアクセスに受信と送信にWinsockCtrlを使用しています。

このWinsockはconnectからclosesocketするまで排他にはできないのでしょうか?

現状同時アクセス時に先アクセスがcloseするまでに後アクセスのconnectが発生しているような結果になっています。


引用返信 編集キー/
■14896 / inTopicNo.2)  Re[1]: Winsockについて
□投稿者/ taka (25回)-(2008/02/28(Thu) 15:38:43)
言わんとしていることが分かるような分からないような。

リクエストをシーケンシャルに処理したいってことですか?
ちなみにWinSockはちょっとだけやりましたがVB6はほとんどやったことないです^^;

No14865 (モー さん) に返信
> Winxpサーバーアプリから共通のポートでVB6のdllを用い、クライアントのアクセスに受信と送信にWinsockCtrlを使用しています。
>
> このWinsockはconnectからclosesocketするまで排他にはできないのでしょうか?
>
> 現状同時アクセス時に先アクセスがcloseするまでに後アクセスのconnectが発生しているような結果になっています。
>
>
引用返信 編集キー/
■14898 / inTopicNo.3)  Re[1]: Winsockについて
□投稿者/ επιστημη (844回)-(2008/02/28(Thu) 16:03:26)
επιστημη さんの Web サイト
> このWinsockはconnectからclosesocketするまで排他にはできないのでしょうか?
> 現状同時アクセス時に先アクセスがcloseするまでに後アクセスのconnectが発生しているような結果になっています。

TCP-stream接続なら、close以前に受け付けたconnect要求に対し"acceptしなきゃいいじゃん"って
思っちゃうんですけど、WinsockCtrlがそれを許さないのでしょうか?

引用返信 編集キー/
■14926 / inTopicNo.4)  Re[2]: Winsockについて
□投稿者/ 片桐 (74回)-(2008/02/28(Thu) 18:29:39)
片桐 さんの Web サイト
Winsockの動きで考えると、ポートあけて、待機して、処理終わったらクローズ、という考えは変わらないと思うのですけれど、ポートオープンしてます?
オープンするとそのポートは独占されるので、他アプリや他プロセスからのアクセスは拒否されるはずですけれど。

他プロセスから処理できているというのは、何かそうとわかる現象がでているのでしょうか?
引用返信 編集キー/
■14933 / inTopicNo.5)  Re[1]: Winsockについて
□投稿者/ はつね (477回)-(2008/02/28(Thu) 21:13:28)
はつね さんの Web サイト
No14865 (モー さん) に返信
> 現状同時アクセス時に先アクセスがcloseするまでに後アクセスのconnectが発生しているような結果になっています。

ちょっと説明が分かりづらいのですが、以下のような状況と思っていいのでしょうか。

【状況推測1】
(1)クライアントアプリAからサーバアプリにConnectしてサーバアプリが処理開始
(2)クライアントアプリAの処理が完了する前に、クライアントアプリBからサーバアプリにConnectしようとして待ち
(3)サーバーアプリでクライアントアプリAの処理が完了
(4)(2)で待ちになっていたクライアントアプリBがサーバアプリにConnectしてサーバアプリが処理開始

【状況推測2】
(1)クライアントアプリAからサーバアプリにConnectしてサーバアプリが処理開始
(2)クライアントアプリAの処理が完了する前に、クライアントアプリBからサーバアプリにConnectしてサーバアプリが処理開始


> このWinsockはconnectからclosesocketするまで排他にはできないのでしょうか?

「排他にはできないか」とはどのような動きが希望なのでしょうか。

【希望動作推測1】
(1)クライアントアプリAからサーバアプリにConnectしてサーバアプリが処理開始
(2)クライアントアプリAの処理が完了する前に、接続してきたものはすべてDisconnect(Connect待ちにさせない)

【希望動作推測2】
・状況推測1の動作をさせたい


引用返信 編集キー/
■14934 / inTopicNo.6)  Re[3]: Winsockについて
□投稿者/ ロック (3回)-(2008/02/28(Thu) 21:22:33)
このdllを呼んでいるアプリのポートは1つしかなく、その同じポートに対して複数クライアントからアクセスが来る構造になっております。

資源節約の為にそうしております。(この部分の変更は仕様として変更は難しいです)

動きとしては同時アクセス時に先クライアント(A)のDataArrival処理が終了し、closeに移行する前に、後クライアント(B)のconnect処理が開始され、
Aの処理が不正になってしまいます。(Aの残処理中のコントロールデータがBのモノに変わってしまう:IPやPort等)


その後のBの動きは単独アクセス時と同じく動作しcloseします。





引用返信 編集キー/
■14935 / inTopicNo.7)  Re[1]: Winsockについて
□投稿者/ 出水 (3回)-(2008/02/28(Thu) 21:29:45)
connectが飛んでくる、ってのは相手がconnectすれば飛んできちゃうと思うので
止めようがないと思います
相手が電話をかけたらベルが鳴るようなもんです

電話に出ない(acceptをしない)とか、
出て忙しいって言ってすぐ切る(エラー返してすぐ切断)とかは出来ますが、
ベルそのものがならないように、ってのは
回線引っこ抜く(サーバのListenを止める)しかないです

…見当違いのこと言ってるかも
引用返信 編集キー/
■14947 / inTopicNo.8)  Re[4]: Winsockについて
□投稿者/ はつね (478回)-(2008/02/29(Fri) 02:21:47)
2008/02/29(Fri) 02:24:10 編集(投稿者)

No14934 (ロック さん) に返信
> このdllを呼んでいるアプリのポートは1つしかなく、その同じポートに対して複数クライアントからアクセスが来る構造になっております。
>
> 資源節約の為にそうしております。(この部分の変更は仕様として変更は難しいです)

仕様的に1ポートしか使わず、そこが使われているときは他は接続できないというのはTCP/IPの基本的な動きです。
なので、現在のプログラムコードはその基本的な動きではなく、一般的なサーバアプリ(複数のクライアントと同時接続する)の動きが中途半端に入ってしまっているのだと思います。
本当にそのサーバアプリは同時に1クライアントアプリとしか接続できなくて良いものなのでしょうか。
本当の姿は、同時に複数クライアントと接続できて、なおかつそのデータがごちゃごちゃにならないようにしなければいけないのではないでしょうか。

同時に1クライアントアプリとしか接続できないようにするのならば次のような流れです。
(1)Winsockコントロールを要素1つの配列として定義します。
(2)sck(0).LocalPortを指定してsck(0).Listenする
(3)sck_ConnectionRequestイベントが発生したら、
   sck配列の要素数が1だったら要素を2にしてsck(1).Accept requestID(イベントプロシージャの第二パラメタ)
sck配列の要素数が2だったらAcceptしないで放置
(4)sck_DataArrivalイベントが発生したらsck(1).GetDataする
(5)データ送受信がおわったらsck(1).Close
(6)sck_Closeイベントが発生したら要素数を1に戻す

参考URL:
http://www.int21.co.jp/pcdn/vb/noriolib/vbmag/9707/vb7_aic.html#C23
引用返信 編集キー/
■14992 / inTopicNo.9)  Re[4]: Winsockについて
□投稿者/ 出水 (4回)-(2008/02/29(Fri) 21:58:39)
> 動きとしては同時アクセス時に先クライアント(A)のDataArrival処理が終了し、closeに移行する前に、後クライアント(B)のconnect処理が開始され、
> Aの処理が不正になってしまいます。(Aの残処理中のコントロールデータがBのモノに変わってしまう:IPやPort等)

もしかして、acceptでconnect状態をもらう時、
クライアント(A)との通信で使っている変数なりクラスなりで受け取ってませんか?

動作から推するに、クライアント(A)と通信に必要な情報が詰まっている部分を、
クライアント(B)と通信する情報で上書きしちゃってるんだと思います
引用返信 編集キー/
■15036 / inTopicNo.10)  Re[2]: Winsockについて
□投稿者/ ロック (4回)-(2008/03/03(Mon) 02:55:13)
2008/03/03(Mon) 12:51:58 編集(投稿者)


はつねさん、出水さんありがとうございます。ご指摘の通りです。

サーバーアプリにthreadを導入したために起きてしまいました。(thread内でWinsockのSendDataを
呼んでいるため、メイン文からdllに戻りArrivalを抜けるタイミングとズレが起きている)

同時アクセスでなければうまく処理できているのですが、アプリからdllに処理が戻ってくる
タイミング次第でdllの情報がまだ処理中にも関わらず後アクセスの情報に上書きされてしまいます。


提案して頂いた参考に再考してみます。
引用返信 編集キー/
■15067 / inTopicNo.11)  Re[3]: Winsockについて
□投稿者/ ロック (5回)-(2008/03/03(Mon) 21:18:39)
1点お聞きしたいのですが、VB6のWinsockでクライアント(A)から受信したデータをサーバー側が別のクライアント(B)に送信する方法はあるでしょうか?

前提としておかしいかもしれませんが、(B)は受信待ちとします。

というのは、同時A,B同時送信で片方がリトライになった際にもう片方の送信時直後になんとかclose、sendをできないかと思いまして。


RemoteHostIpがReadOnlyである以上難しいとは承知しています。
引用返信 編集キー/
■15077 / inTopicNo.12)  Re[4]: Winsockについて
□投稿者/ 出水 (6回)-(2008/03/04(Tue) 07:29:42)
> 1点お聞きしたいのですが、VB6のWinsockでクライアント(A)から受信したデータをサーバー側が別のクライアント(B)に送信する方法はあるでしょうか?

出来ます
AとBで両方ともセッションを確立させた上で、サーバがAの受信データをBに送信すればいいです

> 前提としておかしいかもしれませんが、(B)は受信待ちとします。

受信待ちという意味がaccept前という意味ならば、
コネクションが確立してないうちはいかなるデータも送信できません

> というのは、同時A,B同時送信で片方がリトライになった際にもう片方の送信時直後になんとかclose、sendをできないかと思いまして。
> RemoteHostIpがReadOnlyである以上難しいとは承知しています。

そもそも、TCPのセッションというのは、
こちらが意図していないところでいろいろなデータをやり取りしていますから
変数内のIPを書き換えれば別の相手に届くというものではありません

リトライが発生しているということは、データが届かない状態と推測しますので
sendをしてもデータが届くわけがないです
shutdown,closeは行えますが、データが届かないので相手側に切断したという情報も届きませんが
相手側はいずれタイムアウトということで自動的に切断されると思います

引用返信 編集キー/
■15092 / inTopicNo.13)  Re[5]: Winsockについて
□投稿者/ ロック (6回)-(2008/03/04(Tue) 11:37:54)
No15077 (出水 さん) に返信

出水さん、ありがとうございます。

> AとBで両方ともセッションを確立させた上で、サーバがAの受信データをBに送信すればいいです

これは1ポートで1ソケットでも実現できることでしょうか?
この場合は双方をセッション確立することはできないですよね?


> リトライが発生しているということは、データが届かない状態と推測しますので
> sendをしてもデータが届くわけがないです

内部処理の都合で、受信したけれども送信完了せずに次のアクセスのconnectをしてしまうケースが起こりましたので、
リトライ中はクライアントは受信待ちになり指定してsendすれば届くと推測しています。

引用返信 編集キー/
■15094 / inTopicNo.14)  Re[6]: Winsockについて
□投稿者/ はつね (485回)-(2008/03/04(Tue) 11:53:07)
はつね さんの Web サイト
No15092 (ロック さん) に返信
>>AとBで両方ともセッションを確立させた上で、サーバがAの受信データをBに送信すればいいです
>
> これは1ポートで1ソケットでも実現できることでしょうか?
> この場合は双方をセッション確立することはできないですよね?

通常は双方にコネクションを確立します。
TCP/IPではまずコネクションありきです。コネクションせずにデータの送受信は行えませんし、1コネクションの相手は1つです。
このあたりのTCP/IPの基本原理をまげて通信を行いたいとすれば、TCP/IPを使わずに別の(TCP/IPにとってかわる)プロトコルを選ぶか独自開発するしかないです。


> 内部処理の都合で、受信したけれども送信完了せずに次のアクセスのconnectをしてしまうケースが起こりました

私だったら「内部処理の都合で」じゃなくて「内部処理のバグで」と考えて、TCP/IPを使う御作法に乗っ取ったコードに書き換えると思います。

引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -