画像ファイル
画像ファイル   C#、Vb2005 でSocket通信
 C#のコード 
C#のコード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;


namespace WinSockC
{
public partial class FomSoch : Form
{
public FomSoch()
{
InitializeComponent();
}

//***********************************************************
//初期設定宣言
//***********************************************************
//受信は必ずshift-jisと仮定している
//他の文字の場合はここを変える事
Encoding ecUni = Encoding.GetEncoding("utf-16");
Encoding ecSjis = Encoding.GetEncoding("shift-jis");

//サーバー設定
TcpClient server = null;
//サーバーのリスナー設定
TcpListener listener = null;
//サーバーのセカンドスレッドの設定
Thread threadServer = null;

//クライアント設定
TcpClient client = null;
//クライアントのセカンドスレッドの設定
Thread threadClient = null;


//**********************************************************
//デリゲート宣言
//**********************************************************
//別スレッドからメインスレッドのテキストボックスに書き込むデリゲート
delegate void dlgWriteText(string text);

//引数を持たない汎用のデリゲート
//ストップボタンを押す等に使用
delegate void dlgMydelegate();


//***********************************************************
//ソケット通信の開始処理
//***********************************************************
//Startボタン押下
private void butStart_Click(object sender, EventArgs e)
{
StartSock();
}

//ソケット通信開始
private void StartSock()
{
bool openflg = false;
//チェックボックスを見て sub
//サーバー又はクライアントスタート
if (radioServer.Checked)
{
openflg = ServerStart();
picIndicator.BackColor = Color.Green;
}
else
{
openflg = ClientStart();
}
//ボタンのenableを変える
if (openflg)
{
butStart.Enabled = false;
butStop.Enabled = true;
}
}

//***********************************************************
//セカンドスレッドの作成とサーバーのスタート
//***********************************************************
private bool ServerStart()
{
//TcpListenerを使用してサーバーの接続の確立
try
{
//lisenerが無い場合
if (listener == null)
listener = new TcpListener(IPAddress.Any, int.Parse(textBoxPortNo.Text));

//クライアント接続要求の受付開始
listener.Start();

//ログの書き込み
writeLog("サーバを開始しました。");

//スレッドの作成と開始
threadServer = new Thread(new ThreadStart(ServerListen));
threadServer.Start();
return (true);

}
catch (Exception ex)
{
//エラーが起きた
writeLog("サーバ接続エラー:" + ex.Message.ToString());
listener.Stop();
picIndicator.BackColor = Color.Navy;
return (false);
}
}

//***********************************************************
//別スレッドで実行されるサーバ側の処理
//***********************************************************
private void ServerListen()
{

//クライアントの要求があったら、接続を確立する
//クライアントの要求が有るまでここで待機する
server = listener.AcceptTcpClient();

//ログの書き込みをデリゲートで実行
this.textBoxLog.BeginInvoke(new dlgWriteText(writeLog)
, new object[] { "クライアントが接続しました。" });

//インジケータの色を変える
//バックカラーの変更はデリゲートの必要は無し
picIndicator.BackColor = Color.LightGreen;

//クライアントとの間の通信に使用するストリームを取得
NetworkStream stream = server.GetStream();

//受信文字が入る。
//この数字は少なくても可、少ない場合はLoopが何回か実行される
Byte[] bytes = new Byte[1000];

//受信文字を書き込むデリゲートを作成。
dlgWriteText dlgText = new dlgWriteText(WriteReadText );
while (true)
{
try
{
//受信が無い場合はここで待機する
//文字受信が有った場合とクライアントが接続を切った場合に
//次のステップに進む
int intCount = stream.Read(bytes, 0, bytes.Length);

if (intCount != 0)
{
//intStrCountが0より大きい場合は文字受信有り

//受信部分だけ切り出す
Byte[] getByte=new byte[intCount];
for (int i = 0; i < intCount; i++)
getByte[i] = bytes[i];

byte[] uniBytes;
//'S-Jisからユニコードに変換
uniBytes = Encoding.Convert(ecSjis, ecUni, getByte);

//バイト配列から文字列に変換する
string strGetText = ecUni.GetString(uniBytes);
//受信文字を切り出す

//メインスレッドのテキストボックスに書き込む
textBoxWrite.Invoke(dlgText, strGetText);
}
else
{
//intStrCount=0の場合はクライアントが接続を切った
//デリゲートからログを書き込む
this.textBoxLog.BeginInvoke(new dlgWriteText(writeLog)
, new object[] { "クライアントが切断されました。" });

//サーバの切断と再接続がタイマーを使用して行なわれる
//タイマーはデリゲートで呼ばれる
this.BeginInvoke(new dlgMydelegate(setStartTimer)
, new object[] { });

//ループを抜ける
return;
}

}
catch (System.Threading.ThreadAbortException)
{
//Stopボタンを押すとこのスレッドが削除されこのエラーが起きる。
//それを回避する為のエラー処理。
//切断されたのでループを抜ける
return;
}
catch (Exception ex)
{
//切断で起こるスレッドエラー以外のエラーはここに来る
this.textBoxLog.BeginInvoke(new dlgWriteText(writeLog)
, new object[] { "受信エラー  " + ex.Message.ToString() });
this.butStart.BeginInvoke(new dlgMydelegate(StartSock ),
new object[] { });
//ループを抜ける
return;
}
}
}


//***********************************************************
//セカンドスレッドの作成とクライアントのスタート
//***********************************************************
private bool ClientStart()
{
try
{
//クライアントのソケットを用意
client = new TcpClient(textBoxIp.Text, int.Parse(textBoxPortNo.Text));

//サーバからのデータを受信するループをスレッドで処理
threadClient = new Thread(new ThreadStart(this.ClientListen));
threadClient.Start();

//接続インディケータ
picIndicator.BackColor = Color.LightGreen;
writeLog("クライアント接続接続されました:" );
return (true);
}
catch (Exception ex)
{
writeLog("クライアント接続エラー:" + ex.Message.ToString());
picIndicator.BackColor = Color.Navy;
return(false);
}
}

//***********************************************************
//別スレッドで実行されるクライアント側の処理
//ここの処理はServerと同じなのでそちらを参照のこと
//***********************************************************
private void ClientListen()
{

NetworkStream stream = client.GetStream();

Byte[] bytes = new Byte[100];
dlgWriteText dlgText = new dlgWriteText(WriteReadText);

while (true)
{
try
{
int intCount = stream.Read(bytes, 0, bytes.Length);
if (intCount != 0)
{

//受信部分だけ切り出す
Byte[] getByte = new byte[intCount];
for (int i = 0; i < intCount; i++)
getByte[i] = bytes[i];

byte[] uniBytes;
//'S-Jisからユニコードに変換
uniBytes = Encoding.Convert(ecSjis, ecUni, bytes);
string strGetText = ecUni.GetString(uniBytes);
//受信文字を切り出す
strGetText = strGetText.Substring(0, strGetText.IndexOf((char)0));
textBoxWrite.Invoke(dlgText, strGetText);
}
else
{
//サーバーが切断された
this.textBoxLog.BeginInvoke(new dlgWriteText(writeLog)
, new object[] { "ホストが切断されました。"});
this.butStart.BeginInvoke(new dlgMydelegate(StopSock),
new object[] {});
return;
}
}
catch (System.Threading.ThreadAbortException)
{
//何もしません;
return;
}
catch (Exception ex)
{
this.textBoxLog.BeginInvoke(new dlgWriteText(writeLog)
, new object[] { "受信エラー  " + ex.ToString() });
return;
}
}
}


//***********************************************************
//ソケット通信の終了処理
//***********************************************************
//Stopボタン押下
private void butStop_Click(object sender, EventArgs e)
{
StopSock();
}

private void StopSock()
{
//チェックボックスを見て
//サーバー又はクライアントストップ
if (radioServer.Checked)
CloseServer();
else
CloseClient();
//ボタンのenableを変える
butStart.Enabled = true;
butStop.Enabled = false;
}

//サーバーのクローズ
private void CloseServer()
{
//サーバーのインスタンスが有って、接続されていたら
if (server != null && server.Connected)
server.Close();

//スレッドは必ず終了させること
if (threadServer != null)
threadServer.Abort();

//インディケータの色を変える
picIndicator.BackColor = Color.Navy;
//ログを書き込む
writeLog("サーバーが閉じられました。");

}

//クライアントのクローズ
private void CloseClient()
{
//クライアントのインスタンスが有って、接続されていたら
if (client != null && client.Connected)
client.Close();

//スレッドは必ず終了させること
if (threadClient != null)
threadClient.Abort();

//インディケータの色を変える
picIndicator.BackColor = Color.Navy;
//ログを書き込む
writeLog("クライアントが閉じられました。");
}


//******************************************************
//デリゲートから呼ばれるテキストに書き込むメソド、
//*******************************************************
//受信文字をテキストボックスに書き込む
private void WriteReadText(string text)
{
//受信文字の改行は全て↓に置き換えられる
text = text.Replace("\r\n", "↓");
this.textBoxRead.AppendText(text + "\r\n");
}

//Logを書き込む
private void writeLog(string strlog)
{
this.textBoxLog.AppendText(DateTime.Now.ToString()+" "
+ strlog + "\r\n");
}


//************************************************************
//文字データの送信
//************************************************************
//送信ボタン押下
private void butSend_Click(object sender, EventArgs e)
{
SendStringData();
}

//文字データーの送信
private void SendStringData()
{
//sift-jisに変換して送る
Byte[] data = ecSjis.GetBytes(textBoxWrite.Text);
//送信streamを作成
NetworkStream stream = null;
try
{
//サーバーとクライアントを分けて送信
if (radioClient.Checked)
stream = client.GetStream();
else
stream = server.GetStream();

//Streamを使って送信
stream.Write(data, 0, data.Length);
}
catch
{
MessageBox.Show("送信できませんでした。", "送信エラー");
writeLog("送信エラー:送信できませんでした。" );
}
}
//******************************************************
//別スレッドから抜けて、メインスレッドからStart Stopを
//実行するタイマー
//******************************************************
//デリゲートから呼ばれタイマーをスタートします
private void setStartTimer()
{
timerServerStart.Enabled = true;
}

//通信相手のクライアントが接続を切った時に
//別スレッドからデリゲートを通して呼ばる
private void timerServerStart_Tick(object sender, EventArgs e)
{
timerServerStart.Enabled = false;
StopSock();
//サーバーを再スタートします
StartSock();
}


//******************************************************
//テキストボックスのクリア
//******************************************************
private void butCls_Click(object sender, EventArgs e)
{
textBoxWrite.Clear();
}
private void butClsRead_Click(object sender, EventArgs e)
{
textBoxRead.Clear();
}
private void butClsLog_Click(object sender, EventArgs e)
{
textBoxLog.Clear();
}

//*******************************************************
//プログラムの終了処理
//*******************************************************
private void FomSoch_FormClosing(object sender, FormClosingEventArgs e)
{
CloseServer();
CloseClient();
}
} }

画像 上記C#コードのダウンロード
C#、Vb2005 でSocket通信 本文に戻る   


画像ファイル