Notebook

これは日々の作業を通して学んだことや毎日の生活で気づいたことをを記録しておく備忘録である。

HTML ファイル生成日時: 2025/04/03 13:41:35.024 (台灣標準時)

Python で行う socket を使った通信について

Python で、 socket を使った通信を行う方法を調べてみたので、わかったこ とを記録しておくでござる。

client から server にメッセージを送る方法

まず、 client が serverに文字列を送り、 server がそれを受け取る、とい うことを考えるでござる。 server 側のプログラムは以下のように書けばよい ようでござる。


#!/usr/pkg/bin/python3.13

#
# Time-stamp: <2025/03/14 12:37:13 (UT+08:00) daisuke>
#

###########################################################################

#
# importing modules
#

# importing argparse module
import argparse

# importing socket module
import socket

###########################################################################

###########################################################################

#
# command-line argument analysis
#

# initialising a parser object
descr  = f'server program for socket communication'
parser = argparse.ArgumentParser (description=descr)

# default values
default_server    = '192.168.29.50'
default_port      = 12345
default_maxlength = 256

# adding arguments
parser.add_argument ('-s', '--server', default=default_server, \
                     help=f'IP address of server (default: {default_server})')
parser.add_argument ('-p', '--port', default=default_port, \
                     help=f'port number on server (default: {default_port})')
parser.add_argument ('-l', '--maxlength', default=default_maxlength, \
                     help=f'maximum length of message (default: {default_maxlength})')

# parsing arguments
args = parser.parse_args ()

# arguments
server_address = args.server
server_port    = args.port
maxlength      = args.maxlength

###########################################################################

###########################################################################

#
# communication with client using socket
#

# opening socket
with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as skt:
    # binding socket
    skt.bind ( (server_address, server_port) )
    # starting to listen to client
    skt.listen ()
    # accepting connection
    connection, address = skt.accept ()
    # receiving message from client
    data_from_client_byte = connection.recv (maxlength)
    # converting message from client into UTF-8 string
    data_from_client_str = data_from_client_byte.decode ('utf-8')
    # printing received message
    print (f'Message received from client:')
    print (f'{data_from_client_str}')

###########################################################################

client 側のプログラムは以下のようにすればよいようでござる。


#!/usr/pkg/bin/python3.13

#
# Time-stamp: <2025/03/14 12:37:21 (UT+08:00) daisuke>
#

###########################################################################

#
# importing modules
#

# importing argparse module
import argparse

# importing socket module
import socket

###########################################################################

###########################################################################

#
# command-line argument analysis
#

# initialising a parser object
descr  = f'client program for socket communication'
parser = argparse.ArgumentParser (description=descr)

# default values
default_server    = '192.168.29.50'
default_port      = 12345
default_maxlength = 256

# adding arguments
parser.add_argument ('-s', '--server', default=default_server, \
                     help=f'IP address of server (default: {default_server})')
parser.add_argument ('-p', '--port', default=default_port, \
                     help=f'port number on server (default: {default_port})')
parser.add_argument ('-l', '--maxlength', default=default_maxlength, \
                     help=f'maximum length of message (default: {default_maxlength})')
parser.add_argument ('command', nargs='+', \
                     help=f'command to be sent to server')

# parsing arguments
args = parser.parse_args ()

# arguments
server_address = args.server
server_port    = args.port
maxlength      = args.maxlength
list_command   = args.command

###########################################################################

#
# constructing a command to be sent to server
#

# initialisation of command to be sent to server
command_to_server_str = ''

# making a command
for i in range ( len (list_command) ):
    command_to_server_str = f'{command_to_server_str} {list_command[i]}'

# removing leading white space
command_to_server_str = command_to_server_str.lstrip ()

# conversion from string into byte
command_to_server_byte = command_to_server_str.encode ()

###########################################################################

###########################################################################

#
# communication with server using socket
#

# opening socket
with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as skt:
    # connecting to server
    skt.connect ( (server_address, server_port) )
    # sending a message to server
    skt.sendall (command_to_server_byte)

###########################################################################

192.168.29.50 で test_socket_00_server.py を実行するでござ る。すると、このプログラムは、 client からの接続を待つでござる。


% python3.13 test_socket_00_server.py

server が待ち受けている状態で、別の計算機で test_socket_00_client.py を実行するでござる。


% python3.13 test_socket_00_client.py pointing 12.34 56.78

すると、 server 側に client 側から送った文字列が表示されるでござる。


Message received from client:
pointing 12.34 56.78

server 側でプログラムを実行したところ
fig_202503/socket_00.png
client 側でプログラムを実行したところ
fig_202503/socket_01.png
server 側に client が送った文字列が表示される
fig_202503/socket_02.png

server を何度もメッセージを受け取るようにする

server は常に動いていて、常時コマンドを受け付けるようにしておくと、実 用的な用途に使えそうでござる。 client からのメッセージを一回だけ受け取 り、受け取ったら終了するのではなく、 client からのメッセージを受け取っ たら、また次のメッセージを待ち受けるようにするには、 server 側のプログ ラムを以下のようにすればよいようでござる。


#!/usr/pkg/bin/python3.13

#
# Time-stamp: <2025/03/14 12:37:34 (UT+08:00) daisuke>
#

###########################################################################

#
# importing modules
#

# importing argparse module
import argparse

# importing socket module
import socket

###########################################################################

###########################################################################

#
# command-line argument analysis
#

# initialising a parser object
descr  = f'server program for socket communication'
parser = argparse.ArgumentParser (description=descr)

# default values
default_server    = '192.168.29.50'
default_port      = 12345
default_maxlength = 256

# adding arguments
parser.add_argument ('-s', '--server', default=default_server, \
                     help=f'IP address of server (default: {default_server})')
parser.add_argument ('-p', '--port', default=default_port, \
                     help=f'port number on server (default: {default_port})')
parser.add_argument ('-l', '--maxlength', default=default_maxlength, \
                     help=f'maximum length of message (default: {default_maxlength})')

# parsing arguments
args = parser.parse_args ()

# arguments
server_address = args.server
server_port    = args.port
maxlength      = args.maxlength

###########################################################################

###########################################################################

#
# communication with client using socket
#

# opening socket
with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as skt:
    # binding socket
    skt.bind ( (server_address, server_port) )
    # starting to listen to client
    skt.listen ()
    # waiting for connection from client
    while (True):
        # accepting connection
        connection, address = skt.accept ()
        # connecting with client
        with connection:
            # receiving message from client
            data_from_client_byte = connection.recv (maxlength)
            # converting message from client into UTF-8 string
            data_from_client_str = data_from_client_byte.decode ('utf-8')
            # printing received message
            print (f'Message received from client:')
            print (f'{data_from_client_str}')
            # starting to wait for next connection
            if not data_from_client_byte:
                break

###########################################################################

client 側のプログラムは以下のものでござる。


#!/usr/pkg/bin/python3.13

#
# Time-stamp: <2025/03/14 12:37:38 (UT+08:00) daisuke>
#

###########################################################################

#
# importing modules
#

# importing argparse module
import argparse

# importing socket module
import socket

###########################################################################

###########################################################################

#
# command-line argument analysis
#

# initialising a parser object
descr  = f'client program for socket communication'
parser = argparse.ArgumentParser (description=descr)

# default values
default_server    = '192.168.29.50'
default_port      = 12345
default_maxlength = 256

# adding arguments
parser.add_argument ('-s', '--server', default=default_server, \
                     help=f'IP address of server (default: {default_server})')
parser.add_argument ('-p', '--port', default=default_port, \
                     help=f'port number on server (default: {default_port})')
parser.add_argument ('-l', '--maxlength', default=default_maxlength, \
                     help=f'maximum length of message (default: {default_maxlength})')
parser.add_argument ('command', nargs='+', \
                     help=f'command to be sent to server')

# parsing arguments
args = parser.parse_args ()

# arguments
server_address = args.server
server_port    = args.port
maxlength      = args.maxlength
list_command   = args.command

###########################################################################

#
# constructing a command to be sent to server
#

# initialisation of command to be sent to server
command_to_server_str = ''

# making a command
for i in range ( len (list_command) ):
    command_to_server_str = f'{command_to_server_str} {list_command[i]}'

# removing leading white space
command_to_server_str = command_to_server_str.lstrip ()

# conversion from string into byte
command_to_server_byte = command_to_server_str.encode ()

###########################################################################

###########################################################################

#
# communication with server using socket
#

# opening socket
with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as skt:
    # connecting to server
    skt.connect ( (server_address, server_port) )
    # sending a message to server
    skt.sendall (command_to_server_byte)

###########################################################################

server 側で test_socket_01_server.py を実行するでござる。


% python3.13 test_socket_01_server.py

client 側で test_socket_01_client.py を実行するでござる。


% python3.13 test_socket_01_client.py pointing 12.34 56.78

すると、 server 側に client が送ったメッセージが表示されるでござる。


% python3.13 test_socket_01_server.py
Message received from client:
pointing 12.34 56.78

server は、次のメッセージを待っているので、また client 側のプログラム を実行してみるでござる。


% python3.13 test_socket_01_client.py pointing 23.45 6.78

server 側に、二つ目のメッセージが表示されるでござる。


% python3.13 test_socket_01_server.py
Message received from client:
pointing 12.34 56.78
Message received from client:
pointing 23.45 6.78

server は、ずっと client からの接続を待ち続けるでござる。

server 側でプログラムを実行
fig_202503/socket_03.png
client 側でプログラムを実行
fig_202503/socket_04.png
server 側に client の送った文字列が表示される
fig_202503/socket_05.png
再度 client 側でプログラムを実行
fig_202503/socket_06.png
また server 側に client が送った文字列が表示される
fig_202503/socket_07.png

server 側から client 側に返事をするようにする

client が server にコマンドを送るだけでなく、 server は受け取ったコマ ンドについて、受け付けた旨を client に送り返すようにすると便利そうでご ざる。 server 側のプログラムは以下のようにすればよいようでござる。


#!/usr/pkg/bin/python3.13

#
# Time-stamp: <2025/03/14 12:37:44 (UT+08:00) daisuke>
#

###########################################################################

#
# importing modules
#

# importing argparse module
import argparse

# importing socket module
import socket

# importing time module
import time

###########################################################################

###########################################################################

#
# parameters
#

# file to store telescope status
file_status = 'status.txt'

###########################################################################

###########################################################################

#
# command-line argument analysis
#

# initialising a parser object
descr  = f'server program for socket communication'
parser = argparse.ArgumentParser (description=descr)

# default values
default_server    = '192.168.29.50'
default_port      = 12345
default_maxlength = 256

# adding arguments
parser.add_argument ('-s', '--server', default=default_server, \
                     help=f'IP address of server (default: {default_server})')
parser.add_argument ('-p', '--port', default=default_port, \
                     help=f'port number on server (default: {default_port})')
parser.add_argument ('-l', '--maxlength', default=default_maxlength, \
                     help=f'maximum length of message (default: {default_maxlength})')

# parsing arguments
args = parser.parse_args ()

# arguments
server_address = args.server
server_port    = args.port
maxlength      = args.maxlength

###########################################################################

###########################################################################

#
# functions
#

def is_valid_command (command):
    # initialisation of parameter 'valid'
    valid = False
    # splitting command
    list_command = command.split ()
    # checking command
    match list_command[0]:
        case 'gohome' | 'goflatscreen' | 'pointing' | 'status' | 'tracking':
            valid = True
        case _:
            valid = False
    # return validity of command
    return valid

def write_status (filename, telescope_status):
    with open (filename, 'w') as fh_w:
        fh_w.write (f'{telescope_status}\n')
    return (0)

def execute_gohome (command):
    print (f'Now, going to home position...')
    write_status (file_status, f'status: busy (moving to home position)\n')
    time.sleep (15)
    write_status (file_status, f'status: idling\n')
    print (f'Finished going to home position!')
    return (0)

def execute_goflatscreen (command):
    print (f'Now, going to flatfield screen...')
    write_status (file_status, f'status: busy (moving to flatfield screen)\n')
    time.sleep (15)
    write_status (file_status, f'status: idling\n')
    print (f'Finished going to flatfield screen!')
    return (0)

def execute_pointing (command):
    print (f'Now, pointing telescope to the target...')
    write_status (file_status, f'status: busy (pointing target object)\n')
    time.sleep (15)
    write_status (file_status, f'status: idling\n')
    print (f'Finished pointing telescope to the target!')
    return (0)

def execute_status (command):
    print (f'Now, checking telescope status')
    write_status (file_status, f'status: busy (checking status)\n')
    time.sleep (3)
    write_status (file_status, f'status: idling\n')
    print (f'Finished checking telescope status!')
    return (0)

def execute_tracking (command):
    print (f'Now, changing tracking mode...')
    write_status (file_status, f'status: busy (changing tracking mode)\n')
    time.sleep (5)
    write_status (file_status, f'status: idling\n')
    print (f'Finished changing tracking mode!')
    return (0)

###########################################################################

###########################################################################

#
# communication with client using socket
#

# opening socket
with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as skt:
    # binding socket
    skt.bind ( (server_address, server_port) )
    # starting to listen to client
    skt.listen ()
    # waiting for connection from client
    while (True):
        # accepting connection
        connection, address = skt.accept ()
        # connecting with client
        with connection:
            # receiving message from client
            data_from_client_byte = connection.recv (maxlength)
            # converting message from client into UTF-8 string
            data_from_client_str = data_from_client_byte.decode ('utf-8')
            # printing received message
            print (f'Message received from client:')
            print (f'{data_from_client_str}')
            # checking validity of command
            valid = is_valid_command (data_from_client_str)
            # message sent back to client
            if (valid):
                message_str = f'following command received:\n' \
                    + f'{data_from_client_str}\n'
            else:
                message_str = f'command is invalid!\n' \
                    + f'{data_from_client_str}'
            # conversion from string into byte
            message_byte = message_str.encode ()
            # sending a message back to client
            connection.sendall (message_byte)
            # executing command
            list_command = data_from_client_str.split ()
            match list_command[0]:
                case 'gohome':
                    execute_gohome (data_from_client_str)
                case 'goflatscreen':
                    execute_goflatscreen (data_from_client_str)
                case 'pointing':
                    execute_pointing (data_from_client_str)
                case 'status':
                    execute_status (data_from_client_str)
                case 'tracking':
                    execute_tracking (data_from_client_str)
            # starting to wait for next connection
            if not data_from_client_byte:
                break

###########################################################################

client 側のプログラムは以下のようにしてみたでござる。


#!/usr/pkg/bin/python3.13

#
# Time-stamp: <2025/03/14 12:37:49 (UT+08:00) daisuke>
#

###########################################################################

#
# importing modules
#

# importing argparse module
import argparse

# importing socket module
import socket

###########################################################################

###########################################################################

#
# command-line argument analysis
#

# initialising a parser object
descr  = f'client program for socket communication'
parser = argparse.ArgumentParser (description=descr)

# default values
default_server    = '192.168.29.50'
default_port      = 12345
default_maxlength = 256

# adding arguments
parser.add_argument ('-s', '--server', default=default_server, \
                     help=f'IP address of server (default: {default_server})')
parser.add_argument ('-p', '--port', default=default_port, \
                     help=f'port number on server (default: {default_port})')
parser.add_argument ('-l', '--maxlength', default=default_maxlength, \
                     help=f'maximum length of message (default: {default_maxlength})')
parser.add_argument ('command', nargs='+', \
                     help=f'command to be sent to server')

# parsing arguments
args = parser.parse_args ()

# arguments
server_address = args.server
server_port    = args.port
maxlength      = args.maxlength
list_command   = args.command

###########################################################################

#
# constructing a command to be sent to server
#

# initialisation of command to be sent to server
command_to_server_str = ''

# making a command
for i in range ( len (list_command) ):
    command_to_server_str = f'{command_to_server_str} {list_command[i]}'

# removing leading white space
command_to_server_str = command_to_server_str.lstrip ()

# conversion from string into byte
command_to_server_byte = command_to_server_str.encode ()

###########################################################################

###########################################################################

#
# communication with server using socket
#

# opening socket
with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as skt:
    # connecting to server
    skt.connect ( (server_address, server_port) )
    # sending a message to server
    skt.sendall (command_to_server_byte)
    # receiving a message from server
    reply_from_server_byte = skt.recv (maxlength)
    # conversion from byte into string
    reply_from_server_str = reply_from_server_byte.decode ('utf-8')
    # printing a message from server
    print (f'Reply from server:')
    print (f'{reply_from_server_str}')

###########################################################################

server 側で test_socket_02_server.py を実行するでござる。


% python3.13 test_socket_02_server.py

client 側で test_socket_02_client.py を実行するでござる。


% python3.13 test_socket_02_client.py pointing 12.34 56.78
Reply from server:
following command received:
pointing 12.34 56.78

server 側からの応答が表示されたでござる。 server 側では、 client から のコマンドを受け取ったことが表示されているでござる。


% python3.13 test_socket_02_server.py
Message received from client:
pointing 12.34 56.78
Now, pointing telescope to the target...

しばらくすると、動作が完了したことが表示されるでござる。


% python3.13 test_socket_02_server.py
Message received from client:
pointing 12.34 56.78
Now, pointing telescope to the target...
Finished pointing telescope to the target!

もう一度、 client 側でプログラムを実行してみるでござる。


% python3.13 test_socket_02_client.py status
Reply from server:
following command received:
status

server 側では、 client から送られてきたコマンドが表示されるでござる。


% python3.13 test_socket_02_server.py
Message received from client:
pointing 12.34 56.78
Now, pointing telescope to the target...
Finished pointing telescope to the target!
Message received from client:
status
Now, checking telescope status
Finished checking telescope status!

server 側でプログラムを実行したところ
fig_202503/socket_08.png
client 側でプログラムを実行したところ
fig_202503/socket_09.png
server 側で処理が始まる
fig_202503/socket_10.png
server 側で処理が終了
fig_202503/socket_11.png
client 側でもう一度コマンドを実行
fig_202503/socket_12.png
server 側で処理が終了
fig_202503/socket_13.png

server 側で複数の接続を並行して処理するようにする

server が client からの要請を受けて何か処理をしている間は、別のコマン ドを送っても応答しないのでは不便でござる。 server が複数の接続を並行し て処理するようにするには、 server 側のプログラムを以下のようにすればよ いようでござる。


#!/usr/pkg/bin/python3.13

#
# Time-stamp: <2025/03/14 12:37:54 (UT+08:00) daisuke>
#

###########################################################################

#
# importing modules
#

# importing argparse module
import argparse

# importing socket module
import socket

# importing threading module
import threading

# importing time module
import time

###########################################################################

###########################################################################

#
# parameters
#

# file to store telescope status
file_status = 'status.txt'

###########################################################################

###########################################################################

#
# command-line argument analysis
#

# initialising a parser object
descr  = f'server program for socket communication'
parser = argparse.ArgumentParser (description=descr)

# default values
default_server    = '192.168.29.50'
default_port      = 12345
default_maxlength = 256

# adding arguments
parser.add_argument ('-s', '--server', default=default_server, \
                     help=f'IP address of server (default: {default_server})')
parser.add_argument ('-p', '--port', default=default_port, \
                     help=f'port number on server (default: {default_port})')
parser.add_argument ('-l', '--maxlength', default=default_maxlength, \
                     help=f'maximum length of message (default: {default_maxlength})')

# parsing arguments
args = parser.parse_args ()

# arguments
server_address = args.server
server_port    = args.port
maxlength      = args.maxlength

###########################################################################

###########################################################################

#
# functions
#

def is_valid_command (command):
    # initialisation of parameter 'valid'
    valid = False
    # splitting command
    list_command = command.split ()
    # checking command
    match list_command[0]:
        case 'gohome' | 'goflatscreen' | 'pointing' | 'status' | 'tracking':
            valid = True
        case _:
            valid = False
    # return validity of command
    return valid

def write_status (filename, telescope_status):
    with open (filename, 'w') as fh_w:
        fh_w.write (f'{telescope_status}\n')
    return (0)

def read_status (filename):
    with open (filename, 'r') as fh_r:
        telescope_status = fh_r.read ()
    return (telescope_status)

def execute_gohome (command):
    print (f'Now, going to home position...')
    write_status (file_status, f'status: busy (moving to home position)\n')
    time.sleep (15)
    write_status (file_status, f'status: idling\n')
    print (f'Finished going to home position!')
    return (0)

def execute_goflatscreen (command):
    print (f'Now, going to flatfield screen...')
    write_status (file_status, f'status: busy (moving to flatfield screen)\n')
    time.sleep (15)
    write_status (file_status, f'status: idling\n')
    print (f'Finished going to flatfield screen!')
    return (0)

def execute_pointing (command):
    print (f'Now, pointing telescope to the target...')
    write_status (file_status, f'status: busy (pointing target object)\n')
    time.sleep (15)
    write_status (file_status, f'status: idling\n')
    print (f'Finished pointing telescope to the target!')
    return (0)

def execute_status (command):
    print (f'Now, checking telescope status')
    # checking telescope status
    telescope_status = read_status (file_status)
    print (f'Finished checking telescope status!')
    return (telescope_status)

def execute_tracking (command):
    print (f'Now, changing tracking mode...')
    write_status (file_status, f'status: busy (changing tracking mode)\n')
    time.sleep (5)
    write_status (file_status, f'status: idling\n')
    print (f'Finished changing tracking mode!')
    return (0)

def process_request_from_client (connection, address):
    # connecting with client
    with connection:
        # receiving message from client
        data_from_client_byte = connection.recv (maxlength)
        # converting message from client into UTF-8 string
        data_from_client_str = data_from_client_byte.decode ('utf-8')
        # printing received message
        print (f'Message received from client:')
        print (f'{data_from_client_str}')
        # checking validity of command
        valid = is_valid_command (data_from_client_str)
        # message sent back to client
        if (valid):
            message_str = f'following command received:\n' \
                + f'{data_from_client_str}\n'
        else:
            message_str = f'command is invalid!\n' \
                + f'{data_from_client_str}'
        # conversion from string into byte
        message_byte = message_str.encode ()
        # sending a message back to client
        connection.sendall (message_byte)
        # executing command
        list_command = data_from_client_str.split ()
        match list_command[0]:
            case 'gohome':
                execute_gohome (data_from_client_str)
            case 'goflatscreen':
                execute_goflatscreen (data_from_client_str)
            case 'pointing':
                execute_pointing (data_from_client_str)
            case 'status':
                telescope_status = execute_status (data_from_client_str)
                telescope_status_byte = telescope_status.encode ()
                connection.sendall (telescope_status_byte)
            case 'tracking':
                execute_tracking (data_from_client_str)
                
###########################################################################

###########################################################################

#
# communication with client using socket
#

# opening socket
with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as skt:
    # binding socket
    skt.bind ( (server_address, server_port) )
    # starting to listen to client
    skt.listen ()
    # waiting for connection from client
    while (True):
        # accepting connection
        connection, address = skt.accept ()
        # starting a new thread and processing request from client
        thread = threading.Thread (target=process_request_from_client, \
                                   args=(connection, address) )
        thread.start ()

###########################################################################

client 側のプログラムは以下のようにすればよいようでござる。


#!/usr/pkg/bin/python3.13

#
# Time-stamp: <2025/03/14 12:37:59 (UT+08:00) daisuke>
#

###########################################################################

#
# importing modules
#

# importing argparse module
import argparse

# importing socket module
import socket

###########################################################################

###########################################################################

#
# command-line argument analysis
#

# initialising a parser object
descr  = f'client program for socket communication'
parser = argparse.ArgumentParser (description=descr)

# default values
default_server    = '192.168.29.50'
default_port      = 12345
default_maxlength = 256

# adding arguments
parser.add_argument ('-s', '--server', default=default_server, \
                     help=f'IP address of server (default: {default_server})')
parser.add_argument ('-p', '--port', default=default_port, \
                     help=f'port number on server (default: {default_port})')
parser.add_argument ('-l', '--maxlength', default=default_maxlength, \
                     help=f'maximum length of message (default: {default_maxlength})')
parser.add_argument ('command', nargs='+', \
                     help=f'command to be sent to server')

# parsing arguments
args = parser.parse_args ()

# arguments
server_address = args.server
server_port    = args.port
maxlength      = args.maxlength
list_command   = args.command

###########################################################################

#
# constructing a command to be sent to server
#

# initialisation of command to be sent to server
command_to_server_str = ''

# making a command
for i in range ( len (list_command) ):
    command_to_server_str = f'{command_to_server_str} {list_command[i]}'

# removing leading white space
command_to_server_str = command_to_server_str.lstrip ()

# conversion from string into byte
command_to_server_byte = command_to_server_str.encode ()

###########################################################################

###########################################################################

#
# communication with server using socket
#

# opening socket
with socket.socket (socket.AF_INET, socket.SOCK_STREAM) as skt:
    # connecting to server
    skt.connect ( (server_address, server_port) )
    # sending a message to server
    skt.sendall (command_to_server_byte)
    # receiving a message from server
    reply_from_server_byte = skt.recv (maxlength)
    # conversion from byte into string
    reply_from_server_str = reply_from_server_byte.decode ('utf-8')
    # printing a message from server
    print (f'Reply from server:')
    print (f'{reply_from_server_str}')
    # receiving telescope status
    if (list_command[0] == 'status'):
        telescope_status_byte = skt.recv (maxlength)
        telescope_status_str = telescope_status_byte.decode ('utf-8')
        print (f'Current telescope status = {telescope_status_str}')

###########################################################################

server 側で、 test_socket_03_server.py を実行するでござる。


% python3.13 test_socket_03_server.py

client 側で、 test_socket_03_client.py を実行するでござる。


% python3.13 test_socket_03_client.py pointing 12.34 56.78
Reply from server:
following command received:
pointing 12.34 56.78

server 側では、コマンドを実行し始めるでござる。


% python3.13 test_socket_03_server.py
Message received from client:
pointing 12.34 56.78
Now, pointing telescope to the target...

server 側がコマンドを実行しているときに、 client 側でまたコマンドを実 行してみるでござる。


% python3.13 test_socket_03_client.py status
Reply from server:
following command received:
status

Current telescope status = status: busy (pointing target object)


server 側では、 status コマンドと pointing コマンドの実行が終わったこ とが表示されるでござる。


% python3.13 test_socket_03_server.py
Message received from client:
pointing 12.34 56.78
Now, pointing telescope to the target...
Message received from client:
status
Now, checking telescope status
Finished checking telescope status!
Finished pointing telescope to the target!

また、 client 側でコマンドを実行してみるでござる。


% python3.13 test_socket_03_client.py status
Reply from server:
following command received:
status

Current telescope status = status: idling


server 側の様子は以下の通りでござる。


% python3.13 test_socket_03_server.py
Message received from client:
pointing 12.34 56.78
Now, pointing telescope to the target...
Message received from client:
status
Now, checking telescope status
Finished checking telescope status!
Finished pointing telescope to the target!
Message received from client:
status
Now, checking telescope status
Finished checking telescope status!

server 側でプログラムを実行したところ
fig_202503/socket_14.png
client 側でコマンドを実行したところ
fig_202503/socket_15.png
server 側でコマンドの実行が始まったところ
fig_202503/socket_16.png
server 側でコマンドが実行中に client 側でまたコマンドを実行
fig_202503/socket_17.png
server 側では pointing コマンドの実行中に並行して status コマンドが処理される
fig_202503/socket_18.png
status コマンドに続いて pointing コマンドの実行が終了
fig_202503/socket_19.png
client 側からもう一度コマンドを実行
fig_202503/socket_20.png
server 側の様子
fig_202503/socket_21.png

今後の課題

実際に使えるものを作るためには、考えなければいけないことがまだまだあり そうでござる。コマンドによっては、何かのコマンドの実行中には、実行の開 始を待たねばならぬものがありそうでござる。また、接続を受け付ける相手を 制限することも必要そうでござる。通信内容が関係のない人に見えないように する必要もありそうでござる。標準的な手法がどこかで解説されていないか調 べてみようとおもうでござる。

参考文献



Frequently accessed files

  1. Computer___Python/20220518_0.html
  2. Computer___Network/20230726_00.html
  3. Misc___Taiwan/20240207_00.html
  4. Computer___Network/20230516_00.html
  5. Computer___FreeBSD/20220621_0.html
  6. Computer___Network/20230508_00.html
  7. Computer___Network/20240130_00.html
  8. Computer___Python/20220715_0.html
  9. Food___Taiwan/20220429_0.html
  10. Computer___TeX/20231107_00.html
  11. Computer___NetBSD/20230119_00.html
  12. Computer___Network/20240416_00.html
  13. Computer___Python/20220410_0.html
  14. Computer___Python/20221013_0.html
  15. Computer___NetBSD/20220817_3.html
  16. Computer___Network/20220413_1.html
  17. Computer___Debian/20210223_1.html
  18. Computer___Python/20240101_00.html
  19. Misc___Japan/20240610_00.html
  20. Computer___Python/20210124_0.html
  21. Computer___NetBSD/20220818_1.html
  22. Computer___NetBSD/20220428_0.html
  23. Computer___NetBSD/20240101_02.html
  24. Science___Math/20220420_0.html
  25. Computer___TeX/20230726_01.html
  26. Computer___TeX/20230503_00.html
  27. Science___Astronomy/20220503_0.html
  28. Computer___NetBSD/20230515_00.html
  29. Computer___NetBSD/20220808_0.html
  30. Computer___NetBSD/20240101_03.html


HTML file generated by Kinoshita Daisuke.