クライアント/サーバ:PIPE 1本で双方向通信

2017-02-01 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
以前(2017-01-27)の記事「クライアント/サーバ:Lua - Python プロセス間通信」の如く、
1本のパイプでは“Lua to Lua”、“Lua to Python”の一方向通信は出来た?

そして、
前回(2017-01-30)の記事「Win32 APIの定数:定義は?」で、
イベントについても学習した。

でも、今回はイベントは使わずに、
1本のパイプでの双方向はどうなのか?

学習した。

ここで、
先日(2017-01-25)の記事「クライアント/サーバ:プロセス間通信・改」で書いた:

  ・・・・・
  ・・・・・
  クライアント側 のプログラム(test_Client.gsl)では、
  C の コードで、CreateFileA とか、WriteFile 関数を使っていた。
  でも、このくらいなら Lua のファイルアクセス関数で出来る。
  のでは無いか?

  と云うことで、
  ・・・・・
  ・・・・・
  OK 出来ました。

だったが、ファイルハンドルの対応が分からず、
  Lua のファイルアクセス関数で・・・ は諦めた。

全てを“ffi.C.~”で行くことにした。


先に立ち上げるサーバ側コード:
---------- test_Server_1P2.gsl
charA = |s| ffi.cast( 'char*', s )
ffi.cdef[[ typedef unsigned int DWORD;
int CreateNamedPipeA(
char* lpName, // パイプ名
DWORD dwOpenMode, // パイプを開くモード
DWORD dwPipeMode, // パイプ固有のモード
DWORD nMaxInstances, // インスタンスの最大数
DWORD nOutBufferSize, // 出力バッファのサイズ
DWORD nInBufferSize, // 入力バッファのサイズ
DWORD nDefaultTimeOut, // タイムアウトの間隔
int lpSecurityAttributes // セキュリティ記述子
);
int ConnectNamedPipe( int hNamedPipe, int lpOverlapped );

int ReadFile( int hFile, char* lpBuffer,
DWORD nNumberOfBytesToRead,
void* lpNumberOfBytesRead,
int lpOverlapped );

int WriteFile( int hFile, char* pBuffer,
DWORD nNumberOfBytesToWrite,
void* lpNumberOfBytesWritten,
int lpOverlapped );

int FlushFileBuffers( int hFile );
int DisconnectNamedPipe( int hNamedPipe );
int CloseHandle( int hObject );
]]
----- パイプを作成
P1 = ffi.C.CreateNamedPipeA( charA("\\\\.\\pipe\\pipe1"), 3, 0, 1, 0, 0, 100, 0 )
----- Client オープン待ち
rcd = ffi.C.ConnectNamedPipe( P1, 0 )

Buf=ffi.new('char[256]')
nRd=ffi.new('uint32_t[1]')
nWt=ffi.new('uint32_t[1]')

rcd=ffi.C.ReadFile( P1, Buf, 256, nRd, 0)
str = ffi.string(Buf,nRd[0])
print( str )

rcd=ffi.C.WriteFile( P1, charA(str..'HOGE'), nRd[0]+4, nWt, 0 )
-----
rcd=ffi.C.ReadFile( P1, Buf, 256, nRd, 0)
str = ffi.string(Buf,nRd[0])
print( str )

rcd=ffi.C.WriteFile( P1, charA(str..'HOGE'), nRd[0]+4, nWt, 0 )
-----
rcd=ffi.C.ReadFile( P1, Buf, 256, nRd, 0)
print( ffi.string(Buf,nRd[0]) )

----- 後処理
ffi.C.FlushFileBuffers( P1 )
ffi.C.DisconnectNamedPipe( P1 )
ffi.C.CloseHandle( P1 )
でイイのか?


後で立ち上げるクライアント側コード:
---------- test_Client_1P2.gsl
charA = |s| ffi.cast( 'char*', s )
ffi.cdef[[ typedef unsigned int DWORD;
int CreateFileA(
char* pszFileName, // ファイル名
DWORD dwAccess, // アクセス指定
DWORD dwShare, // 共有方法
int psa, // セキュリティ属性
DWORD dwCreatDisposition, // 動作指定
DWORD dwFlagsAndAttributes, // フラグと属性
int hTemplate // テンプレートファイル
);

int ReadFile( int hFile, char* lpBuffer,
DWORD nNumberOfBytesToRead,
void* lpNumberOfBytesRead,
int lpOverlapped );

int WriteFile( int hFile, char* pBuffer,
DWORD nNumberOfBytesToWrite,
void* lpNumberOfBytesWritten,
int lpOverlapped );

int CloseHandle( int hObject );
]]
----- パイプをオープン
P1 = ffi.C.CreateFileA(charA('\\\\.\\pipe\\pipe1'), 3, 0, 0, 3, 0x80, 0 )

Buf=ffi.new('char[256]')
nRd=ffi.new('uint32_t[1]')
nWt=ffi.new('uint32_t[1]')

rcd=ffi.C.WriteFile( P1, charA('hogehoge'), 8, nWt, 0 )

rcd=ffi.C.ReadFile( P1, Buf, 256, nRd, 0)
print( ffi.string(Buf,nRd[0]) ) ----- 確認
-----
rcd=ffi.C.WriteFile( P1, charA('kamizzz'), 7, nWt, 0 )

rcd=ffi.C.ReadFile( P1, Buf, 256, nRd, 0)
print( ffi.string(Buf,nRd[0]) ) ----- 確認
-----
rcd=ffi.C.WriteFile( P1, charA('_e'), 2, nWt, 0 )

----- 後処理
ffi.C.CloseHandle( P1 )
でイイのか?

DOS窓で、
“test_Server_1P2.gsl”、“test_Client_1P2.gsl”の順に、
ダブルクリックすると、・・・

出来ていますネ。


イベントの処理はイラナイ???


本日はここまで。


“クライアント/サーバ”学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170109
関連記事
スポンサーサイト

コメントの投稿

管理者にだけ表示を許可する

おきてがみ/blogram
blogram投票ボタン



おきてがみ

最新記事
カレンダー
07 | 2017/08 | 09
- - 1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31 - -
月別アーカイブ
カテゴリ
最新コメント
検索フォーム
リンク
プロフィール

<紙>

Author:<紙>
ようこそ。
「パソコンヲタクの雑記帳」
もろもろなことを綴っています。
パソコン ヲタクってねくら?
画像は kami でなく kani です。

カウンター(fc2、i2i) /Google Analytics


i2i(from 2010-08-24)
Total =
Today  =  
Yesterday=
アンチエイジング

Google Analytics
ブックマーク