日記帳だ! with Tux on Libserver

二度目の大改造!! 日記帳…か?を継承し、より柔軟でパワフルなBlogに変身しました。

RSSに対応しています。リンク・コメント・トラックバックは自由にしていただいてほぼ問題ありません。
RSS購読方法、僕のリンク・コメント・トラックバックについての考えを読むことをおすすめします。

JavaScriptを有効にし、Cookieを受け入れ、以下のブラウザを使うことで完全なコンテンツが楽しめます。
Mozilla Firefox 3.0(Get Firefox)・Opera 9.6・Safari 3.2・Lunascape 4/5(Gecko)・Lunascape 5(WebKit)
Internet Explorer 7/8とそれを使うIEコンポーネントブラウザ(Lunascape・Sleipnirなど)

TCPで送受信するIronPythonテスト

コンピュータカテゴリーから、.NET Frameworkカテゴリを分離した。
まぁ順当なところですよね。
あんまり僕はC#に限って物事を書くことはしないのだが、.NET系ではC#ばっかり使うからね。
別に共同で開発している人がVB.NETの人でも問題ないとは思うのだけど…
じゃあIronPythonでも問題ないよ。
ということで、IronPythonでTCP接続のテストをしてみた。
TCPでJSONのやりとりをすれば面白いなぁと思ったわけだ。
まぁその前にTCPでいろいろやるテストをしましょうと。そういうことです。
まず、クライアントだが、こちらは非常に簡単。
# encoding:utf-8
import clr
import System
from System.Net.Sockets import Socket,AddressFamily,SocketType,ProtocolType,SocketShutdown
from System.Net import IPAddress,IPEndPoint
def main():
for i in range(1,11):
mysocket=Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp)
try:
mysocket.Connect("127.0.0.1",1001)
buf=System.Text.Encoding.UTF8.GetBytes( "クライアントより、%d番目のお知らせ"%(i,) )
mysocket.Send(buf)
print '送信済み:%d'%(i,)
mysocket.Shutdown(SocketShutdown.Both)
finally:
mysocket.Close()
System.Threading.Thread.Sleep(1000)
if __name__ == '__main__':
main()
C#のサンプルを見ながら作ってたのだが、何が問題かというとusing構文がないのよね。
だから素直にtry~finallyで書かないといけない。それぐらい書けという話だが。
System.Net.Sockets.Socketクラスを使う。
送るたびにインスタンスを作って、Connectで開いて、Sendで送って、確実にCloseしないといけない。
めんどくさいねぇという話だが、Closeせずに何度もSendすると1つのメッセージになってしまうのよね。
"クライアントより、1番目のお知らせクライアントより、2番目のお知らせ..."みたいに。
送るのはバイト列なので、System.Text.EncodingのインスタンスのGetBytesでバイト列に変換しなくてはいけない。
UTF8については、System.Text.Encoding.UTF8で簡単に取得できるので便利。
Shift_JISは、System.Text.Encoding.GetEncoding("Shift_JIS")、とかしないといけないけど。
あと、Closeする前に、TCPではShutdownを実行するのをおすすめする。どうもそうらしい。
まぁそれにしても列挙型使いすぎだろ。
めんどくさいのは受信側。
非同期で受信待ちをして、受信すると言うことになります。
# encoding:utf-8
import clr
import System
from System.Net.Sockets import Socket,AddressFamily,SocketType,ProtocolType,SocketShutdown
from System.Net import IPAddress,IPEndPoint
def main():
mysocket=Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp)
try:
mysocket.Bind(IPEndPoint(IPAddress.Parse('127.0.0.1'),1001))
mysocket.Listen(1)
mysocket.BeginAccept(System.AsyncCallback(acceptor),mysocket)
print "何かキーを押すと終わります"
System.Console.ReadKey(1)
finally:
mysocket.Close()
def acceptor(ar):
mysocket=ar.AsyncState
client=mysocket.EndAccept(ar)
try:
buf=System.Array.CreateInstance(System.Byte,10)
myms=System.IO.MemoryStream();
while 1:
len=client.Receive(buf)
if len>0:
myms.Write(buf,0,len)
else:
break
res=System.Text.Encoding.UTF8.GetString(myms.ToArray())
print res
print 'from : %s'%(client.RemoteEndPoint,)
client.Shutdown(SocketShutdown.Both)
finally:
client.Close()
mysocket.BeginAccept(System.AsyncCallback(acceptor),mysocket)
if __name__ == '__main__':
main()
まずだが、受信待ちをするためのSocketを作る。Bindで設定して、Listenで待機状態にする。
それにしてもListenの引数って何なんだろう。backlogの数らしいのだが、どのように設定すりゃいいんだ?
BeginAcceptで非同期に待機状態にする。
送受信の要求があれば、acceptorが呼び出される。
ここでEndAcceptすると、クライアントから接続されたSocketを受け取れる。
これを使って送受信すると。Receiveで受け取ることができます。
さて、Receiveメソッドで受け取るのはbyte型配列だと。だからArray.CreateInstanceで配列を作ったんだけどね。
ここで受けるが1回で送りきれないこともあるだろう。そのときどうなるか。
Receiveメソッドの返り値は今回受け取ったバイト数なのだが、
何度もReceiveを繰り返して、これが0になったら終了。
受け取ったバイト列をため込むにはSystem.IO.MemoryStreamクラスが便利らしい。
まぁこれで最後にSystem.Text.EncodingのインスタンスのGetStringで文字列に変換すればOK。
あと、送信元だが、SocketのRemoteEndPointプロパティでわかる。
まぁこれが基本です。
ちょっと複雑なのだが、わかれば楽だと思う。
これ、実はちょっと引数を変えるだけでUDPの送受信ができるようになるんですね。
UDPってことは投げっぱなしというやつですが、
これはこれでおもしろい性質がありますね。
そういうことのテストもすればいいかなと思いますけどね。
まぁしかし確実に受け渡しするならTCPですね、というわけで専らTCPの話をしてきたわけだけど。
これでいろいろ試してみましょうかね。
Author : hidemaro
Date : 2008/10/15(Wed) 23:27
Windows・Microsoft | Comment | trackback (0)

Tools