SkyDrive へ移動 ※ VS2012 用 スレッドを使ってサーバー部分を常駐しますので、プログラムにはコンソールとブラウザと両方からコマンドを送る事になります。 Framework4.5 になって、非同期処理がイベントを作成せずに行単位で処理が継続できるようになったので、コードが簡潔に書けるようになりました。( この処理の場合非同期で行う必要は無いと思いますが ) ブラウザは、IE を使って行うといいと思います。設定で『ウェブサイトを表示するたびに確認する』としておけば、キャッシュによるトラブルも避けられます。 そもそもの目的は、Windows8 ストアアプリよりデータベースアクセスをする為のサーバーとしての利用なので、データベースアクセス用の簡単なテンプレートを用意しています。実際は、Json.NET を使って http で結果を返すつもりにしています。
using System; using System.Collections.Generic; using System.Data.Odbc; using System.IO; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace CHttpServer1 { public class Program { // 引数 public static string[] args; // DB接続文字列 static string cs = "Driver={MySQL ODBC 5.2 Unicode Driver};" + "Server=localhost;" + "Database=lightbox;" + "Uid=root;" + "Pwd=パスワード;"; static void Main(string[] args) { App app = new App(); // イベントの追加 app.OpenDb += open; // ラムダ式による実装 app.Select += (string cmd) => { Console.WriteLine(cmd + " が実行されました"); // select の結果を表示する }; // スレッドイベントを登録 app.ThreadServer += MyThread; // ****************************************** // 終了せずに、コマンドプロンプトを保持する。 // ( "q" で終了 ) // ****************************************** app.Loop(); } // ****************************************** // データーベースを開くイベント // ****************************************** static private void open(string cmd ) { Console.WriteLine(cmd + " が実行されました"); using (OdbcConnection cn = new OdbcConnection(Program.cs)) { try { cn.Open(); } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine("State={0}", cn.State); } Console.WriteLine("処理が終了しました"); } // ****************************************** // http サーバーとしてのイベント( スレッド ) // ****************************************** static private async void MyThread() { Console.WriteLine("スレッドが開始されました"); // HTTP プロトコル用リスナー TcpListener tl = new TcpListener(System.Net.IPAddress.Any, 8080); tl.Start(); TcpClient tc = null; NetworkStream stream = null; StreamReader reader = null; StreamWriter writer = null; string line = null; string lineall = null; bool DataAvailable = true; while (true) { if (DataAvailable) { Console.WriteLine("受信を待機しています....."); } // HTTP の受信待ち tc = tl.AcceptTcpClient(); // 以下は、受信した場合に処理されます // データの入り口 ( NetworkStream ) stream = tc.GetStream(); Thread.Sleep(500); // ストリームを読み込むオブジェクトを取得 reader = new StreamReader(stream); // 実際にデータを読み込んで処理したかどうか DataAvailable = false; // 一回の受信で朱徳した全文字列 lineall = ""; // 実際の全てのデータ取得 if (stream.DataAvailable) { // 非同期で一行取得 while (true) { line = await reader.ReadLineAsync(); // 空でチェックするしかないようです。 if (line == "") { break; } lineall += line + "\n"; } DataAvailable = true; } // http の返信用の書き込みオブジェクトを SHIFT_JIS で作成 writer = new StreamWriter(stream, Encoding.GetEncoding("shift_jis")); // HTTP プロトコルに従って、ヘッダと本文を返す writer.WriteLine("HTTP/1.1 200 OK"); writer.WriteLine("Content-Type:text/plain; charset=Shift_JIS"); int length = (Encoding.GetEncoding("shift_jis")).GetByteCount(lineall); writer.WriteLine("Content-Length: " + length); writer.WriteLine(); writer.WriteLine(lineall); // オブジェクトを閉じる writer.Close(); reader.Close(); stream.Close(); if (lineall == "") { // Console.WriteLine("データがありません"); continue; } Console.WriteLine(lineall); // アドレスバーで、http://localhost:8080/q と入力した場合はスレッドを終了 if ( (lineall+" ").Substring(0, 7) == "GET /q ") { tl.Stop(); break; } } Console.WriteLine("スレッドが終了しました"); } } }
Framework 4.0 でも、static private async void MyThread() の async を削除して、line = await sr.ReadLineAsync(); を line = sr.ReadLine(); にすればビルドできます。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace CHttpServer1 { class App { public delegate void AppHandler( string cmd ); public event AppHandler OpenDb = null; public event AppHandler Select = null; public delegate void ThreadHandler(); public event ThreadStart ThreadServer = null; // ****************************************** // コンストラクタ // ****************************************** public App() { } // ****************************************** // 終了せずに、コマンドプロンプトを保持する。 // ****************************************** public void Loop() { while (true) { // 専用プロンプト Console.Write("app>"); string line = Console.ReadLine(); // 終了コマンド if (line == "q") { break; } // スレッドを開始 if (line == "server") { if (ThreadServer != null) { Thread ts = new Thread(ThreadServer); ts.Start(); } } // DBを開く if (line == "open") { if (OpenDb != null) { OpenDb(line); } } // select 実行の表示 if (line == "select") { if (Select != null) { Select(line); } } } } } }
関連する記事 ■ コンソールアプリケーション(C#) で、クラス、デリゲート、イベント、ラムダ式の振舞いを理解する ■ VB.net : クライアントが送ったヘッダを表示するだけの HTTPサーバーU ■ HTTP コマンド・リスナー :【VB.NET】
|
【VS(C#)の最新記事】
- Replit : cs-list
- C# : Excel の新しいブックのデフォルトのシートのセルに直接値をセットして、オートフィルを Range オブジェクトから実行する
- C#( Form ) : ウインドウ枠の無い吹き出しの作成
- C# のタプル( Visual Studio 2017 でテスト )
- C# : インターネット上の JSON ファイルのフォーマットを クラスとして定義して1行でオブジェクト化して使用する
- C# の文法的文字列処理
- C# : System.Data.Odbc によるデータベースのテーブルからのデータ取得処理( サンプルの SQL は MySQL 用です )
- C# : Excel を データベースとして DataGridView に読み込む
- C# : dynamic 型 による Excel へのアクセス
- C# : フォームを表示せずに、通知領域にアイコンを表示させる常駐プログラム
- Microsoft Access に対してSQLを入力してその結果を DataGridView に表示する最も簡単なコード
- C# : System.Data.Odbc データ取得(SELECT)処理( MySQL ) : ※ using 無し( Dispose 実行 )
- C# : SQL 文を外部テキストにして、String.Format でデータ部分を置き換えて利用する
- C# コンソールアプリを AN HTTPD で実行
- C# : SQLServer( SQLExpress ) の SMO を使用してテーブルの CREATE TABLE 文 を取得する
- C# : DataGridView に TKMP.DLL の IMAP(POP3) で受信したメールを非同期に表示する( 添付ファイルも取得 )
- C# : TKMP.DLLを使った、メール送信テンプレート
- C# と VB.net : TKMP.DLL を使って IMAP でメール本文の一覧を取得する( コンソール )
- C# でDataTable と DataSource を使用して、DataGridView にデータを表示するテンプレート( 行をダブルクリックしてダイアログを表示して行データを処理 )
- (C#) / VS2010 または VS2012 : TKMP.DLL(3.1.2 または 3.1.8)を使った、『さくらインターネット』用メール送信テンプレート