私はRedHat7.5で作業しています。
私はsystemdソケット(/etc/systemd/system/barfoo.socket)を作成しました:
[Unit]
Description=This is the barfoo socket
[Socket]
ListenStream=0.0.0.0:123
NoDelay=true
BindIPv6Only=both
学習者の場合:BindIPv6Only = bothはIPv6およびIPv4ポートを開きます。形式 ListenStream=0.0.0.0:123 IPv4 のポートを明示的に開きます。
そして対応するシステムサービス(/etc/systemd/system/barfoo.service):
学習者の場合:サービスファイルとソケットファイルの名前が同じであることが重要です。
[Unit]
Description=This is the barfoo service
Requires=barfoo.socket
[Service]
RestartSec=2s
User=installation
Group=installation
ExecStart=/home/installation/tests/a.out
Restart=always
[Install]
WantedBy=multi-user.target
学習者の場合:「Requires = barfoo.socket」を使用すると、サービスでソケットを使用できます。 RestartSecとRestartを使用すると、サービスは2秒ごと(終了後)に再開されます。ユーザーとグループを使用すると、インストール権限でサービスを実行できます。 ExecStartは実際の起動バイナリです。
私はまた、小さなテストプログラム(test.c)も作成しました:
#include<stdio.h>
#include<arpa/inet.h>
int main()
{
int server = socket(AF_INET, SOCK_STREAM, 0);
if (server < 0)
printf("Error in server creating\n");
else
printf("Server Created\n");
struct sockaddr_in my_addr, peer_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = INADDR_ANY;
my_addr.sin_addr.s_addr = inet_addr("10.0.1.10");
int b = 1, i = 123;
my_addr.sin_port = htons(i);
b = bind(server, (struct sockaddr*) &my_addr, sizeof(my_addr));
if(b)
printf("Error binding to port %d, return %d\n", i, b);
else
printf("Bound to port %d, return %d\n", i, b);
return 0;
}
それから私は次のことをしました。
gcc test.c
(これはa.outを生成します)systemctl daemon-reload
(これはsystemdが私のbarfooファイルを読むことを可能にします)systemctl start barfoo
これにより、netstat -tulpen
systemdがポートを開いたことがわかります。ただし、サービス(a.out)は常に「ポートバインディングエラー...」を返します。
アイデアは、rootではなく特権で実行されているプログラムでポート123を使用できるようにすることです。通常、1024 未満のポートはルートでのみ使用できます。
私の質問は次のとおりですなぜ動作しないのですか/私が間違っているのですか?
答え1
私は何が間違っていましたか?
実際のテストプログラムコードを書いていません。
ほぼすべてのコード行これまではテストプログラムでは不要でした。 systemdはソケットを開いてバインドし、開いたファイル記述子としてプログラムに渡しました。 まったく自分で作りました。
return 0;
現在はプログラムで唯一適切なステートメントです。
プログラムがリスニングプログラムか受信プログラムかを決定する必要があります。リスナーはリスナーソケットから開かれたファイル記述子を受け取ります。受諾者は、許可された接続ソケットから開かれたファイル記述子を受け取ります。
追加読書
- https://unix.stackexchange.com/a/331104/5132
- Lennart Potlinget al。
sd_listen_fds()
。システムのマニュアルページ。 freedesktop.org.
答え2
ポート123はネットワークタイムポートです。 ntpdやchronydサービスがあるか、ネットワークタイムプロトコル(NTP)を使用してサーバーの時刻を同期する他のサービスはありますか?
カスタムサービスの場合は、/etc/servicesファイルにまだ定義されていないポートを使用することをお勧めします。