CGIとしてPythonを使用したときにSocket通信が通らない。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
しろうと

CGIとしてPythonを使用したときにSocket通信が通らない。

#1

投稿記事 by しろうと » 5年前

現在ApatcheサーバーにおいてCGIとしてPythonを利用し、Socket通信を用いてRaspberryPi(シングルボードコンピュータ)の遠隔操作を果たそうと考えているものです。

今回はCGIとしてsocketを用いるとデータが転送できないという問題があり、質問いたしました。

作成したプログラムの流れとしましては、Apacheサーバーにブラウザで接続し、表示される制御画面のボタンをクリックするとそれに対応した処理を起こすコードをsocketによりクライアントの端末に転送するというものです。
おそらく詳しい方であれば「処理が面倒であり、WebGpioを使用すればよい」と思われる事と思いますが、いかんせん私が端末間通信に慣れていないのもあり、グローバル環境下で動作し、ブラウザで使用できるものを、と考えるとこのようなサーバーにログインし、相手端末にコードを転送して制御するといったものになってしまいました。
(これともうひとつデータベースにIPを保持し、webgpioのページに直接リダイレクトさせるという方法も考えております。)

ここで今回の問題に至るのですが、サーバーおよびクライアント側のPythonプログラムをCGIではなく単体で実行すると動作したのですが、CGIとして実行するとsocket.socket()において何らかの異常が起こっている模様でサーバーにデータを転送できていない模様です。
(ブラウザの開発者画面ではエラーが現れていないが、そこより下の処理が実行されていない為。)
インターネット検索を行ってみたのですが情報もあまりなく途方に暮れている次第です。何故socketの生成が行えていないのでしょうか。
どなたか詳しい方がいらっしゃいましたらぜひとも助言をお願いいたします。
又、端末のグローバル制御をhtmlにて行う手法について詳しい方がいらっしゃる場合は、制御方法の助言もお願いいたします。

よろしくお願いします。

追記:
下記はプログラムになります。全てローカル環境下で試しました。ipはグローバルではないのですが一応伏字にいたしました。

クライアント側のプログラム

コード:

import socket

if __name__ == "__main__":
	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
		s.bind(("ip_num", 50007))
		s.listen(1)
		while(True):
			conn, addr = s.accept()
			with conn:
				while True:
					data = conn.recv(1024)
					print(data)
					if not data:
						break
					if(int(data.decode(utf-8)) == 1):
						#take action
						print("action")
					conn.sendall(b"you correctly transmitted data.")
サーバー単体のプログラム

コード:

import socket

while True:
	word = input("enter: ")
	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
		s.connect(("ip_num", 50007))
		s.sendall(word.encode("utf-8"))
		data = s.recv(-1)
		print(repr(data))
Apacheサーバー、制御画面

コード:

<html>
	<head>
		<meta charset = "utf-8">
	</head>
	<body>
		<center>
		<font size=10>
		WELCOME!!!
		<br>
			<form action="/cgi/control.py" method = "post">
				<input type = "submit" name="handler" value="led">LED</input>>
			</form>
		</center>
	</body>
</html>
CGIとしてのクライアント

コード:

#!/usr/bin/env python
# coding:utf-8
import cgi
import socket
print("Content-type: text-html\n\n")
form = cgi.FieldStorage()

if form["handler"].value == "led":
	print("led turned on")
	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
		s.connect(("ip_num", 50007))
		s.sendall(word.encode("utf-8"))
		data = s.recv(-1)
		print(repr(data))

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: CGIとしてPythonを使用したときにSocket通信が通らない。

#2

投稿記事 by YuO » 5年前

CGIのソケットが繋がっていない,という問題ですよね。
サーバー側のエラーログにはどのように出力されていましたか。

ありがちなのは,CentOS等を使っていてSELinuxのアクセス制御に引っかかっているというものでしょうか。
httpd_can_network_connectあたりがfalseだと接続できません。
ref) 「SELinuxのせいで動かない」撲滅ガイド - Qiita

しろうと

Re: CGIとしてPythonを使用したときにSocket通信が通らない。

#3

投稿記事 by しろうと » 5年前

申し訳ありません。
環境の記載をいたしておりませんでした。
OSにはLubuntuを使用しており、基本的な環境を入れてあるだけでSELinuxは入れておりません。
又、ログを見るという初歩的なことを忘れていました。。。(すいません。。。)

下記がエラーログになります。
やはりsocketの部分でエラーが生じているように感じます。
AttributeErrorが生じているのも気がかりですが。。。
(もしかしてcontrol.pyなるモジュールがpython内に初めから存在している?)

コード:

[Thu Jan 03 23:46:07.542229 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215: Traceback (most recent call last):: /var/wanwan_cgi/control.py, referer: http://192.168.13.131/
[Thu Jan 03 23:46:07.547039 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215:   File "/var/wanwan_cgi/control.py", line 11, in <module>: /var/wanwan_cgi/control.py, referer: http://192.168.13.131/
[Thu Jan 03 23:46:07.547097 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215:     : /var/wanwan_cgi/control.py, referer: http://192.168.13.131/
[Thu Jan 03 23:46:07.547129 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:: /var/wanwan_cgi/control.py, referer: http://192.168.13.131/
[Thu Jan 03 23:46:07.547196 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215: AttributeError: /var/wanwan_cgi/control.py, referer: http://192.168.13.131/
[Thu Jan 03 23:46:07.547214 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215: : : /var/wanwan_cgi/control.py, referer: http://192.168.13.131/
[Thu Jan 03 23:46:07.547229 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215: __exit__: /var/wanwan_cgi/control.py, referer: http://192.168.13.131/
[Thu Jan 03 23:46:07.547239 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215: : /var/wanwan_cgi/control.py, referer: http://192.168.13.131/

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: CGIとしてPythonを使用したときにSocket通信が通らない。

#4

投稿記事 by YuO » 5年前

Ubuntuのサーバー周りもPythonもわからないのですが,エラーとコードを見た感じから。
しろうと さんが書きました:
5年前

コード:

[Thu Jan 03 23:46:07.542229 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215: Traceback (most recent call last):: /var/wanwan_cgi/control.py, referer: http://192.168.13.131/
[Thu Jan 03 23:46:07.547039 2019] [cgi:error] [pid 1040] [client 192.168.13.1:51915] AH01215:   File "/var/wanwan_cgi/control.py", line 11, in <module>: /var/wanwan_cgi/control.py, referer: http://192.168.13.131/
しろうと さんが書きました:
5年前

コード:

	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
エラーが発生している11行目は2回目のwith文の箇所ですよね。
  • 2度socketを開くことに意味があるのか
  • 名前がsで被っているが,これは文脈上問題があるのでは無いか
あたりが気になります。
後者は根本的にエラーになってもおかしくないかと思いますが……。

しろうと

Re: CGIとしてPythonを使用したときにSocket通信が通らない。

#5

投稿記事 by しろうと » 5年前

返信が遅れてしまい申し訳ありません。
問題が解決いたしましたので、報告に参りました。

socketの生成が行われないという問題ですが、どうやらwithによる生成がダメだった模様です。
普通に初期化を行うと実行されました。

ここで再び質問なのですが、CGIにおいてはwithを使用してはいけないのでしょうか?
又、それは何故でしょうか?

度重なる質問で申し訳ありませんが、御回答の程お願いします。

返信

“C言語何でも質問掲示板” へ戻る