[
板情報
|
カテゴリランキング
]
したらばTOP
■掲示板に戻る■
全部
1-100
最新50
|
メール
| |
C#、Vb2005 でSocket通信
1
:
RYU
:2010/06/08(火) 00:04:33
いつも参考にさせていただいております。
ソケット通信での受信イベントについて、少々ご指導ください。
C#、Vb2005 でSocket通信 (複数クライアント&非同期処理) では、
public partial class FomServer : Formの
別スレッドからメインスレッドのテキストボックスに書き込むデリゲート
として、直接テキストボックスに書いていますが、イベントを使用して、
処理する方法を教えてください。
/** セカンドスレッドで実行されるサーバーのListen **
の所で、イベント受信時のメソッドを加え、handler.StartRead();
受信イベントは、
private void OnReadComplete(IAsyncResult ar)の
if (bytesRead > 0) { に データを返すコード
を書いています。
上記にて、1度は正常に受信データを確認できますが、
2回め以降は、有効ではないスレッド間の操作とエラーが起こります。
根本的に間違っているかもしれませんが、リスナーが受診時にデータを
受け取れる処理ができればと考えています。クラスを独立させるため、
なるべくイベントで収集出きればと考えます。
以上、よろしくお願いします。
2
:
igoten
:2010/06/08(火) 08:08:04
ちょっとそのコードだけでは何が悪いか判断できませんが、
一回目のデーターを受信したスレッドと2回目のデーターを受信した
スレッドが異なっているのでしょう。
クライアントの方が既に接続してるにもかかわらず再度
接続要求を出して新しいスレッドを作ってしまっているなんて
ことはありませんか。
3
:
RYU
:2010/06/08(火) 18:41:09
ありがとうございます。
恐らく、下記コードのdoの内側にイベント用のコードを書いている事が原因と思いますが、
どのように修正して良いのか分かります。ご指導願います。
private void EventListen()
{
string S_ip = Rip1.Text;
int S_port2 = int.Parse(rpt2.Text);
//TcpListenerを作成
IPAddress ipAddress = IPAddress.Parse(S_ip);
IPEndPoint localEndPoint2 = new IPEndPoint(ipAddress, S_port2);
Event_listner = new TcpListener(localEndPoint2);
Event_listner.Start();
// クライアントの接続を受けるための永久ループ
try
{
do
{
// Listener.AcceptSocketは同期メソドで接続要求が有るまで
//値を返さずここで待機します
// 新しい接続要求ががあると接続を許可して
// 新しいソケットを返します
Socket socketForClient_e = Event_listner.AcceptSocket();
//クライアント毎の接続とフォームのインスタンスを渡す
ServerOpener handler_e = new ServerOpener(socketForClient_e, this);
handler_e.OnRecive += new ServerOpener.Server_recive(on_read);
//読み込みを開始
handler_e.StartRead();
} while (true);
}
4
:
igoten
:2010/06/09(水) 09:21:47
//メインスレッドのテキストボックスに書き込む
fomServer.Invoke (new dlgWriteText(fomServer.WriteReadText)
, new object[] { this,strGetText });
ここでエラーが出るのですか?
5
:
RYU
:2010/06/09(水) 09:41:52
そこを書き換えて、イベントが発生するようにしています。
public class Server_ER_data : EventArgs
{
public string ip;
public int port;
public string d1;
public string d2;
//Recive data constructer
public Server_ER_data(string ip, int port, string d1, string d2)
{
this.ip = ip;
this.port = port;
this.d1 = d1;
this.d2 = d2;
}
}
public class ServerOpener
{
// EvevntHandler Datarecive Server_R_Data
public delegate void Server_recive(object r, Server_ER_data r_data);
public event Server_recive OnRecive;
・・・・・・・・・・
6
:
RYU
:2010/06/09(水) 09:47:38
すみません。続きです。
private void OnReadComplete(IAsyncResult ar)
{
try
{
//受信文字をStreamから読み込みます
if (networkStream == null)
return;
//受信バイト数が返る
int bytesRead = networkStream.EndRead(ar);
if (bytesRead > 0) //受信文字が有った
{
//受信部分だけ切り出す
Byte[] getByte = new byte[bytesRead];
for (int i = 0; i < bytesRead; i++)
getByte[i] = buffer[i];
byte[] uniBytes;
//'S-Jisからユニコードに変換
uniBytes = Encoding.Convert(ecSjis, ecUni, getByte);
string orMsg = BitConverter.ToString(getByte);
//バイト配列から文字列に変換する
string strGetText = ecUni.GetString(uniBytes);
//受信文字を切り出す
// 相手先を調べる
IPEndPoint r_ip1 = (IPEndPoint)this.socket.RemoteEndPoint;
string rip = Convert.ToString(r_ip1.Address);
// 受信ポートを調べる
IPEndPoint l_port = (IPEndPoint)this.socket.LocalEndPoint;
int lp = Convert.ToInt16(l_port.Port);
//event handler
Server_ER_data rr = new Server_ER_data(rip, lp, orMsg, strGetText);
OnRecive(this, rr);
//とりあえず返信する
WriteString(uniBytes);
//次の受信を待つ
networkStream.BeginRead(buffer, 0, buffer.Length, callbackRead, null);
としています。
ここのOnRecive(this, rr);でイベントを発生させ、呼び出し側で、
受信データの処理を行いたいと思っています。
サンプルでは、直接フォームのテキストに書いていますが、一度受取、処理したいと考えています。
良い方法をご指導願います。
7
:
igoten
:2010/06/09(水) 10:59:44
それでどの行でエラーが出るのでしょうか?
8
:
RYU
:2010/06/09(水) 20:57:52
度々、すみません。自己解決できました。
public class ServerOpener
{
// EvevntHandler Datarecive Server_R_Data
public delegate void Server_recive(object r, Server_ER_data r_data);
public event Server_recive OnRecive;
で、制御元より、イベントを受け取るメソッドのなかで、リストボックスに
追記する制御を行っており、この部分が2度目にエラーとなりました。
ここで、直接リストボックスを制御せず、ここにInvokeでスレッドを作り、
処理を渡しました。
質問のしかたに問題があり、お手数をおかけしました。
ありがとうございました。
お手が空きました、IPアドレスをポーリングして、データを収集するサンプルを
お教えいただければと思います。
新着レスの表示
名前:
E-mail
(省略可)
:
※書き込む際の注意事項は
こちら
※画像アップローダーは
こちら
(画像を表示できるのは「画像リンクのサムネイル表示」がオンの掲示板に限ります)
スマートフォン版
掲示板管理者へ連絡
無料レンタル掲示板