ネットワークプログラミング、Linuxシステムプログラミング
- ネットワークプログラミングの初日:
- ネットワーク通信(TCP通信)を行う
- ネットワーク プログラミング 2 日目:
- ネットワーク プログラミング 3 日目:
- ネットワーク プログラミング 4 日目:
ネットワークプログラミングの初日:
ネットワーク通信(TCP通信)を行う
クライアント:
1.ソケットの作成
2.バインドバインディング
3.接続接続
4.recv送信データを受け付けて送信する
5.close ソケットを閉じます
サービスターミナル:
1. ソケットソケットの作成
2.バインドバインディング
3.listen リスニング(検出)最大接続数
4.応答を受け入れる
5.送信、受信受信、送信
6.閉じる閉じる
最初の関数はソケットを作成します
函数原型 int socket(int domain, int type, int protocol);
头 文 件:#include <sys/socket.h>
参 数: domain: 是地址族
AF_INET
PF_INET // internet 协议
PF_UNIX // unix internal协议
PF_NS // Xerox NS协议
PF_IMPLINK // Interface Message协议
type : 套接字类型】】
SOCK_STREAM // 流式套接字 TCP常用
SOCK_DGRAM // 数据报套接字 UDP常用
SOCK_RAW // 原始套接字
protocol :参数通常置为0
返回值: 如果成功返回socket描述符 失败返回-1,错误存入errno中
写个代码 创建套接字
2 番目の関数バインド バインディング
函数原型: int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
函数参数:sockfd 是socket描述符 socket函数的返回值
addr struct sockaddr的结构体变量的首地址,指向 sockaddr_in
addrlen 是 sizeof (struct sockaddr_in)
struct sockaddr //通用结构体 {
sa_family_t sa_family; //2字节:地址族, AF_xxx
char sa_data[14]; //14字节:协议地址
};
struct sockaddr_in //专用IPv4结构体{
sa_family_t sin_family; /* 2字节:地址族: AF_INET或AF_INET6等 */
in_port_t sin_port; /* 2字节:端口按网络字节顺序排列 */
struct in_addr sin_addr; /* 4字节:ip互联网地址 */
char sin_zero[8]; 8 bytes unused,作为填充
};
struct in_addr {
uint32_t s_addr; /* 4字节:以网络字节顺序排列的地址 */ };
3番目の機能:バイトオーダー変換
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
作用:本机字节序转换long类型的网络字节序
uint16_t htons(uint16_t hostshort);
作用: 本机字节序转换成short类型的网络字节序
uint32_t ntohl(uint32_t netlong);
作用: 网络字节序转换成long类型的本地字节序
uint16_t ntohs(uint16_t netshort);
作用: 网络字节序转换成short类型的本地字节序。
作用: 把ip和端口和当前程序绑定
4 番目の関数: 文字列をネットワーク バイト オーダーに変換する
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
函数原型:in_addr_t inet_addr(const char *cp);
函数作用: 将字符串转换成网络字节序
参数: 需要转换的字符串
返回值: 网络字节序。
函数原型:char *inet_ntoa(struct in_addr in);
函数参数: in_addr 结构体变量
返回值: 点分十进制字符串
5つ目の機能:モニタリング
int listen(int sockfd, int backlog);
パラメータ: sockfd ソケット記述子
バックログの最大接続数
6番目の機能:レスポンス
函数原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
函数参数:sockfd 是socket描述符
addr 客户端的地址,等价来电显示。保存了客户端的ip和端口,传出参数
addrlen 结构体的大小(结构体长度)
堵塞函数
返回值:返回值是客户端的socket描述符。
7 番目の機能: 受信と送信
函数原型:ssize_t send(int sockfd, const void *buf, size_t len, int flags);
函数参数:sockfd 是客户端的socket描述符
buf 需要发送的数据buf
len 发送的数据长度
flags 堵塞和非堵塞的标志 0位堵塞。
函数返回: 实际发送的数据长度,失败返回 -1
函数原型: ssize_t recv(int sockfd, void *buf, size_t len, int flags);
函数参数: sockfd 是客户端的socket描述符
buf 需要接受的数据buf
len 接受的数据长度
flags 堵塞和非堵塞的标志 0位堵塞。
函数返回: 实际接受的数据长度,失败返回 -1
8 番目: ソケットを閉じる
close(套接字)
9位:クライアント接続機能
函数原型:int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
函数参数: sockfd 套接字描述符 客户端自己的
addr 服务器的ip和端口的结构体。
addrlen 结构体大小。
ネットワークの概念:
IP地址:逻辑地址,网络通信的唯一标志,使用点分十进制表示 “192.168.1.4”
IPV4:32位。最多分配40亿ip地址,ip地址已经不足够使用。
ipv6:128位,非常多。足够分配,
DHCP: 動的アドレス割り当てプロトコル インターネット アクセスが必要な場合、未使用の IP アドレスが DHCP サーバーからリースされ、ホストはその IP アドレスを使用してネットワークにアクセスします。使用後、DHCP サーバーは IP アドレスを取り戻し、他の人が使用するのを防ぎます。
物理アドレス: ネットワーク カード アドレス、48 ビット 各ネットワーク カードには固定の番号があり、その番号がネットワーク カード アドレス、つまり MAC アドレスになります。2 つの部分の最初の 24 桁 – メーカー番号と個人番号の最後の 24 桁
さまざまなプロトコルの分析: (理解)
FTP (File Transfer Protocol): TCP 上で動作する、ネットワーク上の 2 台のコンピュータ間でファイルを転送するためのプロトコルです。FTP プロトコルは TCP ポート 20 と 21 を使用します。ポート 20 はデータ交換に使用され、ポート 21 は接続の確立に使用されます。
ディレクトリとファイルへのアクセス、アップロードとダウンロードは許可されますが、ファイルをリモートで実行することはできません。
TFTP (Trivial File Transfer Protocol): クライアントとサーバー間の単純なファイル転送に使用されるプロトコルで、単純かつ低コストのファイル転送サービスを提供し、UDP ポート 69 を使用します。
HTTP (ハイパーテキスト転送プロトコル): WWW サーバーからローカル ブラウザにハイパーテキストを転送するために使用される転送プロトコルです。これにより、ブラウザの効率が向上し、ネットワーク送信が削減されます。
DNS (Domain Name System): インターネット上ではドメイン名と IP アドレスが 1 対 1 で対応しています。ドメイン名は人間にとって覚えやすいですが、機械はお互いの IP アドレスしか認識できません。両者の間の変換は次のとおりです。
ドメイン名解決と呼ばれます。ポート 53 を使用します。
SMTP (Simple Mail Transfer Protocol): TCP の上に構築され、信頼性が高く効率的な電子メール送信を提供するプロトコルです。SMTP は、FTP ファイル転送サービスをモデルとした電子メール サービスです。
主に、システム間で電子メール情報を送信し、電子メール関連の通知を提供するために使用されます。ポート 25 を使用します。
Telnet (リモート ログイン プロトコル): TCP 上に構築されたログインおよびエミュレーション プログラムであり、その基本機能は、ユーザーがログインしてリモート コンピュータ システムにアクセスできるようにすることです。
DHCP (Dynamic Host Configuration Protocol): UDP 上に構築され、クライアント/サーバー モデル (B/S モデル) に基づいて設計された LAN ネットワーク プロトコルです。
TCP: 伝送制御プロトコル。ユーザー プロセスに信頼性の高い全二重バイト ストリームを提供します。
IP: インターネット プロトコル。パケット配信サービスを提供します。
ICMP: Internet Control Message Protocol (インターネット制御メッセージ プロトコル)。ルーターとホスト間で循環されるエラー メッセージと制御メッセージを処理します。制御メッセージとは、ネットワークが接続されているかどうか、ホストに到達可能かどうか、ルートが利用可能かどうかなど、ネットワーク自体に関するメッセージを指します。 pingコマンドなど。
ARP: ipv4 アドレスを MAC アドレスにマッピングするアドレス解決プロトコル
RARP アドレス解決プロトコル、MAC アドレスを IP アドレスに変換します。
tcpとudpの違いを解説(ポイント)
TCP是基于连接的通信,UDP是非连接通信
TCP是可靠传输,数据不丢失,而UDP是不可靠传输,有可能丢失
TCP是在传输层,UDP也在传输层
TCP需要三次握手,而UDP不需要。
UDP传输速度快,发送小尺寸数据,适合做视频等较大数据的传输
TCP是一对一通信,而UDP可以一对多通信。
TCP是基于数据流通信,而UDP是基于数据报通信
サブネットマスク: ネットワークアドレス部分とホストアドレス部分を区別するために使用されます。サブネット マスクもドット付き 10 進表記の 32 ビットで表現され、IP アドレスと 1 対 1 に対応します。サブネット マスクの 1 は IP アドレスのネットワーク部分を表し、0 はホスト部分を表します。
例: 私の IP アドレスは 192.168.5.169 で、サブネット マスクは 255.255.255.0 11000000.10101000.00000101.10101001
11111111.11111111.11111111.00000000
で
あるため、ネットワーク アドレス部分は次のようになります。 92.1 68.5 ホストアドレス部分は 169
(理解)
クラス A: (1.0.0.0- 126.0 .0.0) (デフォルトのサブネット マスク: 255.0.0.0 または 0xFF000000) 最初のバイトはネットワーク番号、最後の 3 バイトはホスト番号です。このタイプの IP アドレスの先頭は「0」である
ため、アドレスのネットワーク番号の範囲は 1 ~ 126 になります。通常、大規模なネットワークで使用されます。(最初のビットは 0 でなければなりません)
クラス B: (128.0.0.0-191.255.0.0) (デフォルトのサブネット マスク: 255.255.0.0 または 0xFFFF0000) 最初の 2 バイトはネットワーク番号、最後の 2 バイトはホスト番号です。このタイプの IP アドレスの最初の部分は「10」である
ため、アドレスのネットワーク番号の範囲は 128 ~ 191 になります。通常、中規模のネットワークに使用されます。
クラス C: (192.0.0.0-223.255.255.0) (サブネットマスク: 255.255.255.0 または 0xFFFFFF00) 最初の 3 バイトがネットワーク番号、最後のバイトがホスト番号です。このタイプの IP アドレスの先頭は「110」である
ため、アドレスのネットワーク番号の範囲は 192 ~ 223 になります。通常、小規模なネットワークに使用されます。
クラス D: マルチキャスト アドレスです。このタイプの IP アドレスの先頭は「1110」であるため、アドレスのネットワーク番号の範囲は 224 ~ 239 になります。通常、マルチキャスト ユーザーに使用されます。
クラス E: は予約されたアドレスです。このタイプの IP アドレスの先頭は「1111」であるため、アドレスのネットワーク番号の範囲は 240 ~ 255 になります。IP ネットワークでは、通常、最小の IP アドレスがネットワーク自体の識別に使用され、
最大の IP アドレスがネットワークのブロードキャスト アドレスとして使用され、他のすべての IP アドレスはネットワーク内のホストに割り当てられます。ただし、LAN 内のホストはインターネットに直接アクセスできず、
ゲートウェイまたはプロキシとして機能するネットワーク アドレス変換サービス (NAT) を介してインターネットにアクセスする必要があります。そのネットワークのインターネット ゲートウェイの最初または最後の IP アドレスを予約するのが一般的です。
3回の握手と4回の手を振る(写真を見てください、強調が強調されています)
ジョブ: クライアントはサーバーにデータを継続的に送信できます。サーバーは受信したメッセージごとに ok を返します。クライアントが bye を送信すると、サーバーとクライアントの両方がシャットダウンされます。
ネットワーク プログラミング 2 日目:
UDP通信
服务器 客户端
socket socket
bind bind
recvfrom sento
close close
UDP 通信数据发送:
関数数原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
函数作用: 在使用udp时候发送数据。(也可以用于tcp)
函数参数:sockfd 是socket的返回值 描述符
buf 需要发送数据的缓存 一般是malloc或者数组
len 需要发送的数据长度
flags 是否堵塞 0为堵塞
dest_addr 发送服务器的地址结构体
addlen 结构体地址长度
返回值:成功返回实际发送的数据字节数 失败返回-1
UDP通信データ受付
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
函数参数:sockfd 是socket的返回值 描述符
buf 需要接受数据的缓存 一般是malloc或者数组
len 需要接受的buf的数据长度
flags 是否堵塞 0为堵塞
src_addr 发送服务器的地址结构体
addlen 结构体的长度的地址
返回值:成功返回实际接受到的数据,失败返回-1
函数作用:在UDP通信是接受数据(也可以用于TCP)
演習: クライアントはファイルをサーバーに送信します。クライアントが送信するときは、まずデータ パケットと一緒に構造体を送信する必要があります。
構造は struct file{ int size char buf【128】; int flags }
ブロードキャスト通信:
一个发送端,多个接收端,所有当前网络的用户都可以接受到消息,一对多的关系。
单播: 一对一 ,广播是一对所有。
多播: 也叫组播,某一部分可以收到,另外一个部分收不到。(中间)
广播地址:最大的主机地址就是广播地址,192.168.5.124的广播地址192.168.5.255
广播是属于UDP通信方式。
客户端(发送) 服务器(接受)
socket socket
bind bind
设置允许广播 设置允许广播
设置广播地址为接收端地址 数据接受
数据发送 接续接受
关闭 关闭
ブロードキャストを設定します。
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
函数作用:设置广播(只是其中一个功能)
函数参数: sockfd 是socket描述符
level 选项定义的层次,SOL_SOCKET (设置socket属性)
IPPROTO_TCP(设置tcp属性)
optname 需要设置或者获取的套接字的选项。 SO_BROADCAST
optval 指针,指向存放所获得选项的缓冲区。 如果是1则设置广播,如果是0则取消广播
optlen 指针 ,上一个参数的长度
返回值:如果成功返回0,失败返回-1
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
函数作用:获取socket的状态信息(获取接受发送缓存区等)
多播通信:也叫作组播通信,给某一部分发送消息
多播地址:D类地址,起始是224.0.0.0~239.255.255.255 。
在进行组播数据发送过程中,可以先自定义一个多播地址。把自己的ip地址加入到多播地址后,给多播地址发送数据,当前组中所有成员都可以收得到 。
客户端 (发送端) 服务器端(接收端)
socket socket
bind(选择) bind
设置允许多播 设置允许多播
加入到多播 加入到多播
给多播发数据 收数据
关闭 退出多播
关闭
setsockopt はマルチキャストを設定します。
IP マルチキャスト通信は IP マルチキャスト アドレスに依存する必要があります。IPv4 では、224.0.0.1 ~
239.255.255.255 の範囲のクラス D IP アドレスであり、ローカル リンク マルチキャスト アドレス、予約済みマルチキャスト アドレス、管理用マルチキャスト アドレスに分けられます。権限マルチキャスト アドレス:
1) ローカル リンク マルチキャスト アドレス範囲は 224.0.0.0 ~ 224.0.0.255 です。これはルーティング プロトコルやその他の目的のために予約されているアドレスです。ルータはこの範囲に属する IP パケットを転送しません。
2) 予約されたマルチキャスト アドレスは 224.0.1.0 ~ 238.255.255.255 で、グローバル (インターネットなど) またはネットワーク プロトコルで使用できます; 3) 管理権
マルチキャスト アドレスは 239.0.0.0 ~ 239.255.255.255 で、使用できます。組織内 プライベート IP アドレスと同様、インターネット上では使用できません マルチキャスト範囲を制限する
解決ブロードキャスト アドレスをルート テーブルに追加するようなデバイスはありません
sudo Route add -net 224.0.0.88 netmask 255.255。 255.255 eth0
1>ソケットを作成します。
2>タイムアウトTTL、ローカルループバック許可LOOPなどのマルチキャストパラメータを設定します。
3>マルチキャストグループに参加する
4>データの送受信
5>マルチキャストグループから離脱します
2. マルチキャスト プログラミングは、setsockopt() 関数と getsockopt() 関数を使用して実装され、マルチキャスト オプションは IP 層にあります。
3.setsockopt() オプション
int setsockopt( int sockfd, int level,int optname, const void *optval, socklen_t optlen );
正常に実行された場合は 0 を返し、それ以外の場合は -1 を返します。
オプション IP_ADD_MEMBERSHIP および IP_DROP_MEMBERSHIP は、
マルチキャスト グループに参加または終了します。オプション IP_ADD_MEMBERSHIP および IP_DROP_MEMBERSHIP を通じて、構造体 struct ip_mreq 型の変数が制御されます。struct ip_mreq のプロトタイプは次のとおりです:
struct in_addr{in_addr_t s_addr;}
struct ip_mreq{ // QQ グループ番号に似たマルチキャスト グループ IP struct in_addr imn_multiaddr; struct in_addr imr_interface; // QQ メンバー番号に似たマルチキャスト グループに追加される IP }
ネットワーク プログラミング 3 日目:
1. マルチキャストプログラミングのプロセス
1>建立一个socket;
2>设置多播的参数,例如超时时间TTL,本地回环许可LOOP等(略)
3>加入多播组 setsocketopt
4>发送和接收数据 (给多播组地址发)
5>从多播组离开 setsockopt
2.多播程序设计使用setsockopt()函数和getsockopt()函数来实现,组播的选项是IP层的。
3.setsockopt()的选项
int setsockopt( int sockfd, int level,int optname, const void *optval, socklen_t optlen );
成功执行返回0,否则返回-1
选项 IP_ADD_MEMBERSHIP 和 IP_DROP_MEMBERSHIP
加入或者退出一个多播组,通过选项 IP_ADD_MEMBERSHIP 和 IP_DROP_MEMBERSHIP,
对一个结 构 struct ip_mreq 类型的变量进行控制,struct ip_mreq 原型如下:
struct in_addr{in_addr_t s_addr;}
struct ip_mreq{
// 多播组 IP,类似于 QQ 群号
struct in_addr imn_multiaddr;
struct in_addr imr_interface; // 将要添加到多播组的 IP,类似于QQ 成员号}
strubt hp mrdq(
strubt hn _ccr hmr multh_ccr;
strubt hn _ccr hmr hntdre_bd;
);
strubt hp mrdq mrdq;
azdro(&mrdq, shzdoe(mrdq));
mrdq.hmr multh_ccr.s _ccr = ine_addr(“224.10.10.1”);
mrdq.hmr hntdre_bd.s _ccr = htonl(INADDR ANY);
setsockopt(sobkec, IPPR0T0_IP, IP_ADD_MEMBER, &mrdq, shzdoe(mrdq));
2.ioモデル
1>堵塞IO模型
最常用,超简单,效果最低。
(read write recv send recvfrom sendto accpet )
(bind listen close socket)
2>非堵塞IO模型
函数不堵塞,直接返回,需要轮询。占用cpu
第一种方式: 直接在recv或者send 或者recvfrom 或者sendto的参数设置非堵塞
例如: recv(fd,buf,sizeof(buf),MSG_DONTWAIT);
第二种方式:fcntl函数设置
int flag = fcntl(fd,F_GETFL,0);
flag |= O_NONBLOCK 接下来的read write等函数都是非堵塞的。
3> 多路复用IO模型
#include <sys/select.h>
函数原型: int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
头 文 件: #include <sys/time.h> #include <sys/types.h> #include <unistd.h>
函数作用:做多路复用函数(等待内核通知,然后再通知给read 或者write函数)
函数参数: nfds 最大描述符值+1
readfds 需要读取的描述符的集合(需要监控的是读缓存)
writefds 需要写的描述符集合(需要监控的是写缓存)
exceptfds 需要异常的描述符集合(监控异常信息)
timeout 超时检测。如果不设置NULL默认是堵塞
返回值: 返回负数 select错误
返回正数: 某些描述符有信号。
返回0则表示等待超时。
以下函数是辅助select函数的使用。
void FD_CLR(int fd, fd_set *set);
函数作用:把所有描述符清空,把fd的描述符在set中清空。
int FD_ISSET(int fd, fd_set *set);
函数作用: 判断fd是否在set描述符集合中。
void FD_SET(int fd, fd_set *set);
函数作用:将fd设置到set描述符集中
void FD_ZERO(fd_set *set);
函数作用: 把描述符集全部清空,编程0;
4>信号驱动模型
发送信号
ケース: UDP 受信側を書き込み、ノンブロッキング (fcntl) に設定し、while1 でデータの読み取りを続けます。データを読み込んだら印刷してください。
ケース: 受信および送信の多重化を監視する必要がある送信者を作成します。(選択後、送信組み合わせと受信セットを監視する必要があります)。
gethostname() はホスト名を取得します
函数原型: int gethostname(char *name, size_t len);
头文件: #include <unistd.h>
函数作用: 获得主机名
函数参数: name 得到主机名,buf存储
len 主机名buf长度
函数原型: int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
函数作用: 获得与套接口相连的远程协议地址
头 文 件: #include <sys/socket.h>
函数参数: sockfd 是socket描述符
addr 用于保存地址的buf
addrlen 保存地址buf的长度
函数原型 struct hostent *gethostbyname(const char *name);
头 文 件: #include <netdb.h>
函数作用:根据主机名取得主机信息
函数参数: *name 主机名
结构体如下: struct hostent {
char *h_name; /* 主机规范名 */
char **h_aliases; /* 别名列表 */
int h_addrtype; /*主机地址类型 */
int h_length; /* 主机地址长度 */
char **h_addr_list; /* 主机地址列表 */
}
案例:
int main() {
struct hostent* addr = gethostbyname("www.baidu.com");
printf("%s\n",(addr->h_addrtype == PF_INET)?"IPV4":"IPV6");
for(int i = 0;addr->h_addr_list[i];++i) {
printf("%s\n" ,inet_ntoa( *(struct in_addr*)addr->h_addr_list[i]));
}
return 0;
}
//自学
getsockname() 获得本地套接口协议地址
gethostbyaddr() 根据主机地址取得主机信息
getprotobyname() 根据协议名取得主机协议信息
getservbyname() 根据服务名取得相关服务信息
getservbyport() 根据端口号取得相关服务信息
焦点: ネットワーク プロパティを設定します。
setsockopt() はソケット オプションを取得/設定します
函数原型:int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
sockfd:一个标识套接口的描述字
level:选项定义的层次。支持的层次仅有SOL_SOCKET(socket属性)和
IPPROTO_TCP(tcp属性)IPPROTO_IP
optname:需设置的套接口选项。
optval:指针,指向存放所设置选项值的缓冲区。
optlen:指针,指向optval缓冲区的长度值。
プレビュー: UNIX 通信と遅延処理。
ネットワーク プログラミング 4 日目:
1.unix域socket
不属于网络通信内容,只在多进程之间通信。(ipc的一种通信方式)
两种方式:tcp和udp
通过普通文件的路径名来识别socket,不需要提供ip地址。
unlix 用の TCP ドメイン ソケット
服务器 客户端
socket socket
bind bind
listen connect
accept ....
read read
write write
close close
流程:
首先创建socket。int fd =socket(PF_UNIX,SOCK_STREAM.0);
其次绑定结构体:
struct sockaddr_un {
sa_family_t sa_prefix 协议簇
char sun_path[108]; 路径名
};
再度: バインド関数をバインドします。
次に、リッスン、accpet、読み取り、書き込みクローズします。
注: Unix では、バインドする前にファイルが存在しないことを確認するように注意する必要があります。Remove を使用して、事前にバインド ファイルを削除できます。間違いを防ぎます。
ネットワーク遅延検出:
setsockeopt 関数、3 番目のパラメーターは SO_RECVTIMEO — 受信遅延時間を設定します
SO_SENDTIMEO — 送信遅延時間を設定します
4 番目のパラメーター: 構造体 simeval 構造
体 注: ヘッダー ファイル #include<sys/time.h > を追加する必要があります
struct timeval
{ __time_t tv_sec; /* 秒数/ __suseconds_t tv_usec; /マイクロ秒数*/ };