4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

python#Socket通信

Posted at

ネット上には情報たくさんありますのでここでSocket通信とはなにかを説明しなくてよいだと思います。

https://qiita.com/megadreams14/items/32a3eed4661e55419e1c
http://research.nii.ac.jp/~ichiro/syspro98/socket.html
https://qiita.com/tatsuya4150/items/474b60beed0c04d5d999

PythonではSocketのモジュールがあり、今回はこれを使います。
サンプルコードはサーバー側とクライアント側に分けてます。

簡単なメッセージを投げてみよう

まずサーバがずっとリクエストが待って、クライアントがリクエストきたらwelcome to my server!を返しします。

サーバー側

import socket

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((socket.gethostname(),8020))
s.listen(5)

while True:
	clientsocket,address=s.accept()
	print('Connection from {} is established'.format(address))
	clientsocket.send(bytes('welcome to my server!','utf8'))
	clientsocket.close()

クライアント側

import socket

#a stream of data is coming, you should define how long of your track.
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((socket.gethostname(),8020))

#buffer
msg=s.recv(1024)
#beacause we are receiving the byte, we need to decode the bytes.
print(msg.decode('utf-8'))
s.close()


Terminalからみると…
image.png

うん~なんだか行きそうですね。
クライアント側のmsg=s.recv(1024)の1024ちょっと気になるね。これを(1)にしたらどうになるのかな。

import socket

#a stream of data is coming, you should define how long of your track.
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((socket.gethostname(),8020))

#buffer
Entire_msg=''
while True:
	msg=s.recv(1)
	print(msg)
	Entire_msg+=msg.decode('utf-8')
	if len(msg) <=0 :
		break


#beacause we are receiving the byte, we need to decode the bytes.
print(Entire_msg)
s.close()

なるほど、msg=s.recv(1)は毎回もらうのデータサイズを決めるってことだね~
image.png

FIX_HEADERをつけてみよう

三菱CPUのMC-Protocolとか色々なHeaderがあるじゃない?それはなになにFrameとかデータのアドレスをどこから取るとか、
何個アドレス取るとか。ここで仮に簡単FIX_HEADERを作ってみますね~

FIX_HEADERの仕様:
長さ:20
MESSAGEの文字列の長さ+SPACE
例えば、Welcome to the serverなら、21 Welcome to the serverになります。

import socket
import time

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((socket.gethostname(),8020))
s.listen(5)

FIX_HEADER=20

while True:
	
	msg='Welcome to the server'
	le= str(len(msg))
	msg=le+(FIX_HEADER-(len(str(len(msg)))))*' '+msg

	clientsocket,address=s.accept()
	print('Connection from {}'.format(address))
	clientsocket.send(bytes(msg,'utf8'))

こっちはクライアント側です:

import socket


FIX_HEADER=20

#a stream of data is coming, you should define how long of your track.
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((socket.gethostname(),8020))

while True:
	#buffer

	full_msg=''
	new_msg=True
	while True:
		msg=s.recv(10)
		if new_msg:
			print('new message:{}'.format(msg[:FIX_HEADER]))
			print(msg[:FIX_HEADER])
			msglen=int((msg[:FIX_HEADER]))
			new_msg=False

		full_msg+=msg.decode('utf-8')

		if len(full_msg)-FIX_HEADER == msglen:
			print('All Recv..')
			print(full_msg[FIX_HEADER:])
			new_msg=True
			full_msg=''

	print(full_msg)

うん、大丈夫そうですね。
image.png

Python Objectを送ってみよう

ここで使われてるのPythonのPickleモジュールです。サンプルコードは辞書を使うですが、
場合によってJSONでもLISTでもなんでもOKです!

こちはサーバ側です:

import socket
import time
import pickle

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((socket.gethostname(),8020))
s.listen(5)

FIX_HEADER=20

while True:
	
	# msg='Welcome to the server'
	d={1:'Hello',2:'I am here'}
	msg=pickle.dumps(d)
	print(msg)
	le= str(len(msg))

	header=(((le+(FIX_HEADER-(len(str(len(msg)))))*' ')))

	header2=bytes(header.encode())
	msg=header2+msg
	

	clientsocket,address=s.accept()
	print('Connection from {} is established on {}'.format(address,time.time()))
	
	clientsocket.send(msg)

クライアント側:

import socket
import pickle

FIX_HEADER=20

#a stream of data is coming, you should define how long of your track.
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((socket.gethostname(),8020))

while True:
	#buffer

	full_msg=b''
	new_msg=True
	while True:
		msg=s.recv(10)
		if new_msg:
			print('new message:{}'.format(msg[:FIX_HEADER]))
			print('*')

			msglen=int((msg[:FIX_HEADER]))
			print(msglen)
			new_msg=False

		full_msg+=msg
		print(full_msg)

		if len(full_msg)-FIX_HEADER == msglen:
			print('All Recv..')
			print(full_msg[FIX_HEADER:])

			d=pickle.loads(full_msg[FIX_HEADER:])

			new_msg=True
			
			print('*')
			print(d)

うん、大丈夫ですね!
image.png

以上になりますが、今回ここでSocket一回自分の手でやってみたらPLCとかでなんでここでこんな設定にならないと
だめなんだ?とか少しわかると気がします。

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?