LinuxのCでは、2つのプログラムを使用するにはどうすればよいですか。後者は、stdoutを使用して最初に表示されるテキストデータを送信しますか?
-
28-10-2019 - |
質問
私はシンプルを書いています インスタントメッセンジャー プログラム L Linuxのc.
今、私はそのプログラムを持っています ソケットにバインドします ローカルマシンのポートへ、そして テキストを聴きます 私のローカルマシンIPとポートに接続された別のプログラムによって送信されるデータ。
まあ、私はこのクライアントに私のプログラムにテキストデータを送信させ、それを使用して表示することができます stdout
私のローカルマシンで。しかし、私は クライアントマシンにデータを送り返す方法をプログラムできません, 、私のプログラムはクライアントマシンから送信されたテキストを聞くことと表示するのに忙しいからです。
新しいプロセスを作成するにはどうすればよいですか(クライアントマシンから送信されたテキストを聴いて表示し、そのテキストを取得して他のプログラムに送信します stdout
, 、他のプログラムが世話をします stdin
クライアントマシンに送信されます)または、個別のジョブ(送信、受信、表示)を行う2つのプログラムを作成し、適切なデータを互いに送信しますか?
それが奇妙に言葉遣いである場合は申し訳ありませんが、必要かどうかを明確にします。私は調べました exec
, execve
, fork
, など。しかし、これが適切な道を見るべき適切な道であるかどうか、または私が欠けているより単純な方法があるかどうかについて混乱しています。
どんな助けも大歓迎です、ありがとう。
編集: :振り返ってみると、私はこれが2つの別々のプログラムではるかに簡単に達成されると考えました。 1つは、IMサーバー、その他、IMクライアントです。
IMクライアントは、IMサーバープログラムに接続し、IMサーバーに必要なテキストを送信します。次に、IMサーバーは、各クライアントから送信されたテキストに追加されたクライアントの名前/IPを含むバッファ/ファイルで送信されたデータを録音し、そのテキスト(名前の形式:テキスト)を送信します。接続されている各クライアント。
これにより、複雑なプロセス間/プログラムコミュニケーションが必要になります stdin
と stdout
, 、そして代わりに、 簡単なクライアント/サーバーの通信方法を使用します, 、クライアントプログラムがサーバーからそれに送信されるテキストを表示すると stdout
, 、および使用 stdin
サーバーにテキストを送信するには。
これにより、私はまだ私の元の質問に答えている人に興味があります:科学のため。読んでくれてありがとう、そして誰かが私の精神的なブレーンストーミングやコミュニティから来るどんな答えからも恩恵を受けることを願っています。
解決
ただし、クライアントマシンから送信されたテキストをリスニングして表示するのに忙しいため、クライアントマシンにデータを送信する方法をプログラムすることはできません。
リスニングソケットから返品された同じソケット accept()
データの送信と受信の両方に使用できます。したがって、あなたがそれから読んでいるという理由だけで、あなたのソケットは決して「忙しい」ことはありません...あなたは同じソケットに書き戻すことができます。
あなたが同時に読み書きの両方を読み書きする必要がある場合は、から返されたソケットを共有します accept()
2つの異なるスレッドにわたって。ソケットを送信して受信するためにネットワークスタックで2つの異なるバッファーが使用されているため、読み取り専用のスレッドとソケットへの書き込みの別の専用スレッドは、ミューテックスを使用せずにスレッドセーフになります。
他のヒント
私はFork()を使用します - 子供のプロセスを作成すると、1つが受け取ることができ、もう1つは送信できる2つの異なるソケットで2つの異なることを行うことができる2つの異なるプロセスがあります。私はまだこのようなクライアント/サーバーをコーディングすることに関する個人的な経験はありませんが、それはあなたの問題を解決するのが私の最初の刺し傷になるでしょう...
@bdonlanがコメントで述べたように、あなたは間違いなくのような多重化呼び出しが必要です 選択する またはできれば 世論調査 (または関連するsyscallsのような pselect
, ppoll
...)。これらの多重化呼び出しは、いくつかのチャネルを一度に待つための原始的です( pselect
と ppoll
I/Oイベントと信号の両方を原子的に待つことができます)。また読んでください チュートリアルを選択します 男ページ。もちろん、いくつかのファイル記述子を待つことができます。また、読み取り能力と書き込み能力の両方を待つことができます(必要に応じて、同じソケットでも) select
また poll
syscall。
すべてのイベントベースのループとフレームワークは、これらの多重化呼び出しを使用しています( poll
また select
)。使用することもできます libevent, 、または(特にグラフィカルユーザーインターフェイスアプリケーションをコーディングする場合)GTKやQTのようなGUIツールキットはすべて中央のイベントループに基づいています。
マルチプロセスまたはマルチスレッドアプリケーションを使用することは、あなたの場合に役立つとは思いません。イベントループが必要です。
また、取得するように頼むこともできます SIGIO
データがソケットに到着したときの信号を使用して fcntl と F_SETOWN
, 、しかし、これはあなたにとってあまり役に立ちません。その後、多くの場合、ソケットのノンブロッキングを使用したいと思うことがよくあります。