Help us understand the problem. What is going on with this article?

Pythonで遠隔サーバとSocket通信でやりとりしてみた。

ss.png

目的

  • Pythonで遠隔VPSサーバとデータをやりとりする

やっていることの性質上Insecureな部分が多いので、あくまでテスト・趣味を目的としたものです。

環境

  • CentOS 7.8.2003
  • PHP 7.3
  • Python 3.7
  • さくらのVPS(※10周年おめでとうございます!)

サーバ側

サーバを用意します。
私の例ではさくらのVPSを借りました。

環境構築

(注)さくらのVPS利用時の注意点

コントロールパネルからパケットフィルタリング設定を追加してください。
OFFにすることもできますが、セキュリティ上よろしくないので、お勧めしません。

sakura01.png

本例では、50000のポート番号を使いたかったので、一時的にOFFにしました。

image.png

ポート設定

必要に応じて設定してください。
本例ではさくらのVPSの設定例です。
また、ポート番号もお好みに応じて変更されて下さい。

$ firewall-cmd --zone=public --add-port=50000/tcp --permanent

設定の反映もお忘れなく!

$ firewall-cmd --reload

phpをインストール

本例ではphp7.3をインストールします。

remi

$ yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

いろいろ余計なものも入ってしまってますが、必要であれば適時ご変更ください。

$ yum -y install --enablerepo=remi,remi-php73 php php-mbstring php-xml php-xmlrpc php-gd php-pdo php-pecl-mcrypt php-mysqlnd php-pecl-mysql

PHP-WebSocketを使ってソケットサーバ構築

本例では外部ライブラリであるPHP-WebSocketを使います。

ここにあるバイナリをApacheディレクトリに落としてください。

$ cd /var/www/html
$ wget https://github.com/nicokaiser/php-websocket/archive/php-websocket.zip
$ unzip php-websocket.zip
$ sudo rm -rf php-websocket.zip

ダウンロードが終わったら、php-websocket/serverにあるserver.phpを編集します。
vimがインストールされてない場合、viを使用するかyum -y install vimでインストールしてください。

$ cd php-websocket/server
$ vim server.php

'<グローバルIPv4アドレス>'50000(ポート)を適時変更・保存してください。

<?php

error_reporting(0);

require(__DIR__ . '/lib/SplClassLoader.php');

$classLoader = new SplClassLoader('WebSocket', __DIR__ . '/lib');
$classLoader->register();

$server = new \WebSocket\Server('<グローバルIPv4アドレス>', 50000);
$server->registerApplication('echo', \WebSocket\Application\EchoApplication::getInstance());
$server->registerApplication('time', \WebSocket\Application\TimeApplication::getInstance());
$server->run();

次に、php-websocket/lib/WebSocket/Connection.phpにあるハンドシェイク関数を書き換えます。
28行目のhandshake関数を下記のように書き換えます。

private function handshake($data)
{
    socket_write($this->socket, $data, strlen($data));
    $this->application->onConnect($this);
    return true;
}

WebSocketサーバを起動

下記のコマンドで起動します。

$ php server.php

このようになれば、サーバ起動完了です。クライアントに移ります。

[root@~]# php server.php 
2020-09-14 14:02:13 [info] Server created

クライアント側(Python)

データを送信するクライアント側のコードです。

  • '<グローバルIPv4アドレス>'を置き換え
  • 50000はポートです
import socket

if __name__ == '__main__':
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        sock.connect(('<グローバルIPv4アドレス>', 50000))
        data = 'Hello From Python Client!'
        sock.send(data.encode())
        print(sock.recv(1024).decode())

叩いてみる

送信したデータがエコーされれば成功です。
かなりゴリ押し気味ですが、とりあえずできました。

ss.png

[root@myserver]# php server.php 
2020-09-14 15:00:53 [info] Server created
2020-09-14 15:00:55 [info] [client XXX] Connected

おわりに

意外と面倒だった。。
ご覧いただきありがとうございました。

kkent030315
高校生。スカウトお待ちしています https://www.wantedly.com/users/141344544
https://kkent030315.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした