組み込み Linux シリーズ パート 8: ネットワーク ポートの操作
1 はじめに
一部の比較的高性能のマイクロコントローラーにはイーサネット インターフェイスが搭載されていることが多く、ネットワーク ポートはネットワーク プロトコル スタックの動作に関与するため、MCU では比較的複雑な周辺機器と見なされます。通常、ネットワーク プロトコル スタックはリアルタイム オペレーティング システム (RTOS) で実行されるため、一般のマイクロコントローラー開発者がネットワーク ポートを使用するのは困難です。 Linux では、ネットワーク ポートが頻繁に使用されるインターフェイスです。これは、Linux には成熟した完全なネットワーク通信プロトコル スタックがあり、基礎となるドライバーが製造元から提供されているため、比較的使いやすいためです。この記事では、Linux でのネットワーク ポートの使用について簡単にまとめ、皆様のお役に立てれば幸いです。
2環境紹介
2.1.ハードウェア
\1) インターネット上のサードパーティ製 NUC972 開発ボード:

購入に興味のある友達は、淘宝網ストアにアクセスして購入できます:
https://s.click.taobao.com/X8mza8w
この記事では主にボードのネットワーク ポートについて説明します。
\2) USB - RS232 ケーブル 1 本、ネットワーク ケーブル 1 本、電源コード 1 本、Micro USB ケーブル 1 本
2.2.ソフトウェア
\1) 前回の記事から引き続き Uboot とカーネルを使用します。
\2) Buildroot を使用して Rootfs を再生成します。NUC972 Buildroot のダウンロード アドレスは、https://github.com/OpenNuvoton/NUC970_Buildroot です。ここで Buildroot を使用して Rootfs を再生成する理由は、Buildroot ツールを使用して追加するためです。この記事で必要な ssh 機能などは非常に便利で、手動で移植するよりもはるかに簡単です。よくわからないかもしれませんが、興味のある方はオンラインチュートリアルを参照して、dropbear を手動で移植して ssh 機能を実装すると、二つの方法を比較することでより理解が深まります。
3) 前回の記事でもクロスツールチェーン arm_linux_4.8.tar.gz が使われていますが、このツールチェーンも Buildroot によって生成されるものと思われます。
3Buildroot は Rootfs を作成します
詳細な手順はここでは紹介しません。以前に投稿した記事「Buildroot を使用して I.MX6 のルート ファイル システムを作成する」を参照してください。ここではいくつかの点を説明します:
\1) 公式 Buildroot をダウンロードした後、対応するディレクトリに入り、次の手順を実行します。
nuvoton_nuc972_defconfigを作成する###作る###
最初のコンパイル時間は少し長くなりますが、オンラインで大量のファイルがダウンロードされるため、皆さんは辛抱強く待つ必要があります。2) クロスツールチェーンの問題に関しては、Buildroot ツールチェーンが使用されますが、この Buildroot を選択するとツールチェーンが最初から作成されます。コンパイルが完了すると、output/host/ ディレクトリに新しく作成されたツールチェーンが作成されていることがわかりますが、個人的には公式のツールチェーンはこれから来ているのではないかと推測しています。
3) Dropbear はデフォルト設定では選択されていません。自分で選択できます。

4) コンパイルが完了すると、生成された rootfs は、output/images/rootfs.tar になります。これを NUC972 ボードにプログラムできるようにするには、まず解凍してから、生成するために使用する必要があります。 mkyaffs2 を介した .img 形式ファイル。

ネットワーク ケーブルをボードとコンピュータに接続し、コンピュータの IP を 192.168.0.50 に設定し、シリアル ポートのログイン インターフェイスに ifconfig eth0 192.168.0.100 と入力します。起動後にネットワークが利用可能であることを確認するには、これを追加します。 /etc/init.d/rcS ファイルの終わりへの文。これにより、後でシリアル ポートを接続する必要がなく、ネットワーク ポートだけを使用して Linux システムにログインでき、同時にファイルをボードに転送でき、ファイルをコピーする必要がなくなりました。以前と同様に U ディスクを使用すると、効率が大幅に向上します。
4 ネットワークポートの操作
4.1.関連コマンド
ネットワークに関連する一般的なコマンドには、先ほどネットワーク カードを構成するときに使用した ifconfig や、ネットワークにアクセスできるかどうかをテストするために使用した ping などがあります。その他には、後で紹介する Route、ethtool なども含まれます。実際に使用するとき。
4.2.C言語例
最も一般的に使用されるのは udp 通信と tcp 通信です。これらの基本的な概要についてはここでは詳しく説明しません。よくわからない学生は、Baidu で 2 つの記事を読むだけで済みます。ここでは UDP を例として、非常に古典的な例を見てみましょう。

実装する機能は次のとおりです:
\1) クライアントは手動で入力されたデータを受け取ります
\2) クライアントは上記のデータをサーバー
に送信します\3) サーバーは受信したデータをクライアントに送り返します
コードを直接アップロードします:
リーリーまず、gcc を使用して Ubuntu でコンパイルします。arm-linux-gcc をクロスコンパイルしていないことに注意してください。最初に PC 上でサーバーを実行し、次にクライアントを実行します。効果がわかります。これにより、上記のことが実現されます。私たちが欲しい機能について言及しました。

上記のコードをよく読んでください。説明が必要な点がいくつかあります:
1) UDP は TCP とは異なり、リクエストの接続と受け付けのプロセスがありません。したがって、実際にはサーバーとクライアントの間に明確な区別はありません。上記のサーバーとクライアントの名前は説明の便宜上のものです。私は次のように理解しています: send first クライアントが最初にデータ (リクエスト データ) を受信し、サーバーが最初にデータを受信してからデータを送信します。
\2) バインド関数がサーバーの例では呼び出されているのに、クライアントの例では呼び出されないことに気づきましたか?その理由は何ですか?その理由は、サーバーが動作するにはまずデータを受信する必要があるためで、ポートがバインドされていない場合、データをどこで受信するかを知る方法がありません。クライアントがバインドする必要がない理由は、クライアントが最初に送信し、送信後すぐに送信ポートでデータを受信できるためです。
\3) 実際に仕事をしていると、私を含めて多くの人がポートでよく混乱していることがわかりました。ここでまとめると、UDPを受信する場合、このポートからデータを受信する前にポート番号(このポートの自装置のポート)をバインドする必要があり、データ受信後に相手のIPアドレスと送信ポート番号を取得することになります。 。送信時に相手のIPとポートを指定するだけで、本機の送信ポートはランダムに割り当てられるため、ポートをバインドする必要はありません。
ポートをバインドせずに送信されたポートがランダムに割り当てられていることを確認するために、別の小さな実験を行うことができます。クライアントをオフにして、再度開きます。前後に 2 回出力されたポート情報を確認します。 2回のポート番号が異なります。を参照してください。

\4) ソケットを作成するためにソケットを呼び出す場合、関数の 2 番目のパラメーターには SOCK_DGRAM が渡され、UDP プロトコルが使用されることを示します。 TCP の場合、このパラメータは SOCK_STREAM.
です。\5) addr_local メンバー変数に値を割り当てるときに、htonl(INADDR_ANY) を使用して IP アドレスを自動的に取得します。
INADDR_ANY を使用する利点は、ソフトウェアが他のホストで実行される場合、またはホストの IP アドレスが変更される場合に、ソース コードを変更して再コンパイルする必要がなく、ソフトウェアの起動時に手動で入力する必要がないことです。また、1 つのホストに複数の IP アドレスが割り当てられている場合、ポート番号が一致していれば、異なる IP アドレスからデータを受信できます。
\6) クライアントで送信するときに設定した IP は 127.0.0.1 で、これは特別な IP アドレスです。ifconfig を使用して確認できます。Ubuntu およびボード上で確認できます:

インターネットで英語の説明を見つけました:
127.0.0.1 は、「ローカルホスト」とも呼ばれるループバック インターネット プロトコル (IP) アドレスです。このアドレスは、エンドユーザーが使用している同じマシンまたはコンピュータへの IP 接続を確立するために使用されます。単純に理解すると、ローカル マシン自体を表すことになります。
次のステップでは、クライアント コードをクロスコンパイルし、実行するためにボードに配置します。2 つの微妙な変更を加える必要があります:
最初の addr_dest.sin_addr.s_addr=inet_addr(“127.0.0.1”); は次のように変更されます:
addr_dest.sin_addr.s_addr=inet_addr(“192.168.0.50”);
192.168.0.50 は PC の IP アドレスです。
2 番目の while(1) のこれら 3 つの文
文字バフ[1024] = {0x00};
printf(“文字列を入力してください: “);
fgets(buff,1024,stdin);
は次のように変更されました:
char buff[1024] = “TopSemic フレンズの皆さん、こんにちは!”;
//printf(“文字列を入力してください: “);
//fgets(buff,1024,stdin);
目的は、ユーザーによる情報の入力を待たずに、クライアントが自動的にデータを送受信できるようにすることです。
Ubuntu では、scp コマンドを使用して、ファイルをボードの /opt ディレクトリに直接配置します
scp udp_client root@192.168.0.100:/opt

さらに、Ubuntu で ssh コマンドを使用して Linux システムに直接ログインします。
ssh root@192.168.0.100:/opt

このように、Ubuntu ではボードへのログインとボードへのファイルのアップロードのプロセスが簡単に操作できるようになり、以前の Windows シリアル ポート ログインや U ディスク ファイル転送と比較して、はるかに便利です。
Ubuntu で udp_server を大喜びで実行しました。Ubuntu で ssh でボードにログインし、udp_client を実行しました。正常に実行されると思いましたが、予期せぬ事態が発生しました。実際、結果はまったく出力されませんでした。
しかし明らかに、仮想マシン Ubuntu はボードにログインでき、正常に ping でき、ボードは IP 192.168.0.50 にも ping できるのに、なぜ udp が通過できないのでしょうか?その後、しばらく考えた後、問題は解決されました。解決策は次のとおりです:
仮想マシンのデフォルトのネットワーク設定モードは、以下に示す NAT モードです。





最後に、上記のコードの IP を変更します。
addr_dest.sin_addr.s_addr=inet_addr(“192.168.0.80”);
再コンパイル、ダウンロードして一度実行すると、正常に動作します。
追加点: ボードをデバッグする場合、Windows のネットワーク デバッグ アシスタントがよく使用されますが、このツールを使用する場合は、プロトコルの種類、ローカル ホスト アドレス、ローカル ホスト ポート、およびリモート ホストを正しく設定するだけで済みます。 、それを送信して表示します。
たとえば、次のように、Windows のネットワーク デバッグ アシスタントを有効にして、クライアントと仮想マシン サーバー間の通信をシミュレートすることもできます。
5 実践作業の概要
実際の仕事でよくある間違いを教えてください。
プロセッサがネットワーク ポートを介して外部デバイスと通信し、udp 通信を使用すると仮定します。通常のワークフローは次のようになります。最初にデータを送信し、次に外部デバイスが応答します。
このモデルは、上記のサーバー モデルとクライアント モデルに非常に似ており、実装する必要があるのはクライアントです。つまり、最初に sendto 関数を呼び出して送信し、次に recvfrom 関数を呼び出して受信します。通常の状況では、このようなプログラムを作成することに問題はありませんが、実際には、外部デバイスの電源が突然オフになってからオンになったり、通常の動作中に再起動したりするなど、多くの異常な状況を考慮する必要があります (ただし、CPU デバイスの電源は入っていません)。オフ) これにより、どのような問題が発生しますか?外部デバイスの電源がオフになっているため、データを受信できないため、recvfrom 関数はブロックされます。外部デバイスの電源が再投入されて初期化された後でも、データを受信していないため、応答データが返されず、recvfrom 関数が動かないでください。

解决上述问题的办法也很简单,可以设置一个超时,使用setsockopt函数,让接收函数在超时时间内没有接收到数据时就返回就行了。返回后再接着重头发送数据即可,框架如下:
/* 设置阻塞超时 */
struct timeval timeout = {3, 0}; // 设置3s超时
if(setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval))
{
<code style="display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px">printf("time out setting failed "); </code>
}
.
.
.
/* 数据阻塞接收 */
int receivePacketLen = recvfrom(sockfd,buffer,sizeof(buffer),0,(struct sockaddr*)& addr_sender,&addrLen);
if(receivePacketLen != -1)
{
//接收到数据
…
}
else if (errno == EAGAIN) //阻塞接收超时
{
<code style="display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px">printf("udp receive timeout! "); return -1; </code>
}
为了大家更直观的感受这个问题,我们在上面实验的基础上来模拟这个场景,我们先运行upd_client,后运行udp_server,大家看下现象,结果自然是没有数据输出。

道理不难想明白,client程序运行后,先发送了数据,然后就阻塞在读那里不动了。我们把程序简单修改下:
// Max Recv block timeout in second #define gMaxRecvBlockTimeout 3 … … … // Set recv timeout struct timeval timeout = {gMaxRecvBlockTimeout, 0}; if(setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval)) printf("time out setting failed "); } //不断获取用户输入并发送给服务器,然后接受服务器数据 while(1) { char buff[1024] = "Hello TopSemic Friends!"; //printf("Please Input a string: "); //fgets(buff,1024,stdin); sendto(sockfd, buff, strlen(buff), 0, (struct sockaddr*)&addr_dest, sizeof(struct sockaddr_in)); recvlen = recvfrom(sockfd,buff,sizeof(buff),0,(struct sockaddr *)&addr_sender,(socklen_t *)&nlen); if(recvlen > 0) { buff[recvlen] = 0x00; printf("Message form server: %s ", buff); printf("sender ip:%s port:%d ",inet_ntoa(addr_sender.sin_addr),ntohs(addr_sender.sin_port)); } else if(errno == EAGAIN) // 阻塞接收超时 { printf("udp receive timeout! "); } printf("************************************** "); } close(sockfd); return 0;
这时我们先运行client,

打印如上,然后再运行Server,就可以正常工作了,不会再出现上述问题。
以上が組み込み Linux シリーズ パート 8: ネットワーク ポートの操作の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Centosとubuntuの重要な違いは次のとおりです。起源(CentosはRed Hat、for Enterprises、UbuntuはDebianに由来します。個人用のDebianに由来します)、パッケージ管理(CentosはYumを使用し、安定性に焦点を当てます。チュートリアルとドキュメント)、使用(Centosはサーバーに偏っています。Ubuntuはサーバーやデスクトップに適しています)、その他の違いにはインストールのシンプルさが含まれます(Centos is Thin)

Centosのインストール手順:ISO画像をダウンロードし、起動可能なメディアを燃やします。起動してインストールソースを選択します。言語とキーボードのレイアウトを選択します。ネットワークを構成します。ハードディスクをパーティション化します。システムクロックを設定します。ルートユーザーを作成します。ソフトウェアパッケージを選択します。インストールを開始します。インストールが完了した後、ハードディスクから再起動して起動します。

Centosは、上流の分布であるRhel 8が閉鎖されたため、2024年に閉鎖されます。このシャットダウンはCentos 8システムに影響を与え、更新を継続し続けることができません。ユーザーは移行を計画する必要があり、提案されたオプションには、Centos Stream、Almalinux、およびRocky Linuxが含まれ、システムを安全で安定させます。

DockerはLinuxカーネル機能を使用して、効率的で孤立したアプリケーションランニング環境を提供します。その作業原則は次のとおりです。1。ミラーは、アプリケーションを実行するために必要なすべてを含む読み取り専用テンプレートとして使用されます。 2。ユニオンファイルシステム(UnionFS)は、違いを保存するだけで、スペースを節約し、高速化する複数のファイルシステムをスタックします。 3.デーモンはミラーとコンテナを管理し、クライアントはそれらをインタラクションに使用します。 4。名前空間とcgroupsは、コンテナの分離とリソースの制限を実装します。 5.複数のネットワークモードは、コンテナの相互接続をサポートします。これらのコア概念を理解することによってのみ、Dockerをよりよく利用できます。

Centosは廃止されました、代替品には次のものが含まれます。1。RockyLinux(最高の互換性)。 2。アルマリン(Centosと互換性); 3。Ubuntuサーバー(設定が必要); 4。RedHat Enterprise Linux(コマーシャルバージョン、有料ライセンス); 5。OracleLinux(CentosとRhelと互換性があります)。移行する場合、考慮事項は次のとおりです。互換性、可用性、サポート、コスト、およびコミュニティサポート。

CentOSが停止した後、ユーザーは次の手段を採用して対処できます。Almalinux、Rocky Linux、Centosストリームなどの互換性のある分布を選択します。商業分布に移行する:Red Hat Enterprise Linux、Oracle Linuxなど。 Centos 9ストリームへのアップグレード:ローリングディストリビューション、最新のテクノロジーを提供します。 Ubuntu、Debianなど、他のLinuxディストリビューションを選択します。コンテナ、仮想マシン、クラウドプラットフォームなどの他のオプションを評価します。

Dockerデスクトップの使用方法は? Dockerデスクトップは、ローカルマシンでDockerコンテナを実行するためのツールです。使用する手順には次のものがあります。1。Dockerデスクトップをインストールします。 2。Dockerデスクトップを開始します。 3。Docker Imageを作成します(DockerFileを使用); 4. Docker画像をビルド(Docker Buildを使用); 5。Dockerコンテナを実行します(Docker Runを使用)。

VSコード拡張機能のインストールの理由は、ネットワークの不安定性、許可不足、システム互換性の問題、VSコードバージョンが古すぎる、ウイルス対策ソフトウェアまたはファイアウォール干渉です。ネットワーク接続、許可、ログファイル、およびコードの更新、セキュリティソフトウェアの無効化、およびコードまたはコンピューターの再起動を確認することにより、問題を徐々にトラブルシューティングと解決できます。
