読者です 読者をやめる 読者になる 読者になる

Pythonのソケット通信

pythonでソケット通信の方法を勉強してみた。

とは言うものの、ネットワークプログラミングはこれまであまりやったことがなく、手始めにWebからの情報を頼りに勉強した。

そもそもソケットという概念を勉強する必要があった。参考サイトはhttp://goo.gl/92lZ
ソケットとそれを利用する為の概要、関数がまとめられていて、非常に勉強になった。以下にまとめておく。

サーバー側のソケット通信利用の流れ

  1. socket
  2. bind
  3. listen
  4. accept
    ======================
  5. send or recv
    ======================
  6. closesocket

クライアント側のソケット通信利用の流れ

  1. socket
  2. connect
    ======================
  3. send or recv
    ======================
  4. closesocket

そして、具体的なソケット通信を行うpythonソースをhttp://goo.gl/AToL を見て勉強した。上記と照らし合わせると非常に理解しやすい。

サーバー側のserver.pyを実行してから、クライアント側のclient.pyを実行。
server.py

# server.py
#
#
import socket

host = ''
port = 16000

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(1)

print 'Waiting for connections...'
clientsock, clientaddr = s.accept()
while 1:
            rcvmsg = clientsock.recv(1024)
            print 'You received a message > %s' % (rcvmsg)
            if rcvmsg == '':
                   break
clientsock.close()

client.py

# client.py
#
#
import socket

host = 'localhost'
port = 16000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))

while 1:
            print 'Type message you want to send to %s ...' % (host)
            msg = raw_input()
            if msg == '':
              s.close()
              break
            s.sendall(msg)

また、プログラム内の複数処理を並行に実行したい場合、つまりスレッド(Thread)処理の場合は以下の用にThreadServer.pyを作成すれば良いそうです。

ThreadServer.py

#ThreadServer.py
#
#
import socket, threading, time

host = ''
port = 16000

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(1)

def threadfunc(sock):
    print '%s is created!' % (threading.currentThread().getName())
    while 1:
        rcvmsg = sock.recv(1024)
        time.sleep(1)
        if rcvmsg == '':
            break
        else:
            print '%s received -> %s' % (threading.currentThread().getName(), rcvmsg)
    sock.close()
    print '%s is terminated!' % (threading.currentThread().getName())

while 1:
       try:
            clientsock, clientaddr = s.accept()
       except:
            break
       t = threading.Thread(target = threadfunc, args = [clientsock])
       t.setDaemon(1)
       t.start()

各関数の理解にはpythonの仕様を参照しました(http://goo.gl/Vzj3 )。
今後、これを軸に自分なりに編集していこうと思います。

しかし、こう見るとpythonの書き方は本当にC言語を踏襲している。インデントには気を付けるべきですが…
上記参照させて頂いた両サイトには非常に感謝申し上げます。この場を借りてお礼申し上げます。