linux高階程式設計day09 筆記 (轉)
阿新 • • 發佈:2018-12-27
struct sembuf
{
int sem_num;//下標 int sem_op;
int sem_flg;//建議為0.}一.訊號量(同步)
1.回顧:
一個程序控制另外一個程序.
邏輯變數+pause/sleep+訊號
2.訊號量(semaphore)訊號燈
三個資料:紅燈/綠燈/黃燈
60 90 10
訊號量是共享記憶體整數陣列.根據需要定義指定的陣列長度
訊號量就是根據陣列中的值,決定阻塞還是解除阻塞
3.程式設計
3.1.建立或者得到訊號量 semget
3.2.初始化訊號量中指定下標的值 semctl
3.3.根據訊號量阻塞或者解除阻塞 semop
3.4.刪除訊號量 semctl
案例:
A: B
建立訊號量 得到訊號量
初始化訊號量
根據訊號量阻塞 解除阻塞
刪除訊號量
semget函式說明
int semget(key_t key,
int nums,//訊號量陣列個數 int flags);//訊號量的建立標記
//建立IPC_CREAT|IPC_EXCL|0666
//開啟0 返回: -1:失敗
>=0:成功返回訊號量的ID
int semop(
int semid,//訊號量ID struct sembuf *op,//對訊號量的操作.操作可以是陣列多個 size_t nums,//第二個引數的個數 ); 返回:
-1:時失敗
0:成功
int semctl(int semid,
int nums,//對IPC_RMID無意義 int cmd,//SETVAL IPC_RMID );//對IPC_RMID無意義 sem_op:
前提條件訊號量是unsigned short int;
不能<0.
-:夠減,則semop馬上返回,不夠減,則阻塞.
+:執行+操作
0:判定訊號量>0,則阻塞,直到為0
控制程序的搭配方式:
+(解除阻塞) -(阻塞)
0(阻塞) -(解除阻塞)#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//2.1.定義一個聯合體union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
main()
{
key_t key;
int semid; //訊號量ID union semun v;//2.2.定義初始化值 int r;
struct sembuf op[1];
//1.建立訊號量 key=ftok(".",99);
if(key==-1) printf("ftok err:%m\n"),exit(-1);
//semid=semget(key,1/*訊號量陣列個數*/,
// IPC_CREAT|IPC_EXCL|0666);
semid=semget(key,1,0);//得到訊號量 if(semid==-1) printf("get err:%m\n"),exit(-1);
printf("id:%d\n",semid);
//2.初始化訊號量 v.val=2;
r=semctl(semid,0,SETVAL,v);//2.3設定訊號量的值 if(r==-1) printf("初始化失敗!\n"),exit(-1);
//3.對訊號量進行阻塞操作
//3.1.定義操作 op[0].sem_num=0;//訊號量下標 op[0].sem_op=-1;//訊號量操作單位與型別 op[0].sem_flg=0;
while(1)
{
r=semop(semid,op,1);
printf("解除阻塞!\n");
}
//4.刪除(可以不刪除)}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//2.1.定義一個聯合體union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
main()
{
key_t key;
int semid; //訊號量ID union semun v;//2.2.定義初始化值 int r;
struct sembuf op[2];
//1.建立訊號量 key=ftok(".",99);
if(key==-1) printf("ftok err:%m\n"),exit(-1);
semid=semget(key,1,0);//得到訊號量 if(semid==-1) printf("get err:%m\n"),exit(-1);
printf("id:%d\n",semid);
//3.對訊號量進行阻塞操作
//3.1.定義操作 op[0].sem_num=0;//訊號量下標 op[0].sem_op=1;//訊號量操作單位與型別 op[0].sem_flg=0;
op[1].sem_num=0;//訊號量下標 op[1].sem_op=1;//訊號量操作單位與型別 op[1].sem_flg=0;
while(1)
{
r=semop(semid,op,2);
sleep(1);
}
//4.刪除(可以不刪除)
//semctl(semid,0,IPC_RMID);}
{
int sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
} struct in_addr
{
in_addr_t s_addr;
} //總結:
IP地址的表示
字串表示"192.168.0.26"
整數表示:in_addr_t;
字結構表示struct in_addr;
連線點:endpoint
struct sockaddr_in
{
in_port_t sin_port;
struct in_addr sin_addr;
}; 1.3.IP地址的轉換
inet_addr //把字串IP轉換為二進位制整數IP(網路位元組序)
inet_aton //把字串IP轉換為struct in_addr;(網路字結序)
#inet_network//把字串IP轉換為二進位制整數IP(本地位元組序)
inet_ntoa //把結構體struct in_addr轉換為字串IP
4個本地主機位元組序與網路序轉換函式:
h表示主機位元組序,n表示網路位元組序,s表示兩個2位元組,l表示4個位元組
uint16_thtons(uint16_t)
uint32_thtonl(uint32_t)
uint16_tntohs(uint16_t)
uint32_tntohl(uint32_t)
ps:所以傳送時候,埠轉換可以用htons,而ip可以用htonl
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
main()
{
/*
in_addr_t nip=192<<24 | 168 <<16 | 0<<8 | 26;
char *ip="192.168.0.26";
//把整數轉換為字串inet_ntoa
struct in_addr sip;
int myip;
sip.s_addr=nip;
printf("nip:%u\n",nip);
printf("%s\n",inet_ntoa(sip));
myip=inet_addr(ip);
printf("%u\n",myip);
printf("%hhu.%hhu.%hhu.%hhu\n", myip>>24 & 255,
myip>>16 & 255,
myip>>8 & 255,
myip>>0 & 255);
*/
/*
char ip[4]={192,168,0,26};
printf("%d\n",*(int*)ip);
*/
char *ip="10.45.8.1";
struct in_addr addr;
in_addr_t net;
in_addr_t host;
struct in_addr tmp;
inet_aton(ip,&addr);
net=inet_lnaof(addr);
host=inet_netof(addr);
tmp.s_addr=net;
printf("%s\n",inet_ntoa(tmp));
tmp.s_addr=host;
printf("%s\n",inet_ntoa(tmp));
}1.4.IP地址的意義
IP地址的位表達不同意義:
IP地址組建網路:網路標識/主機標識
網路 主機
A類 7 24 網路少 主機
B類 14 16
C類 21 8
D類 組播
E類 沒有使用
1.5.計算機系統中的網路配置
/etc/hosts檔案 配置IP,域名,主機名
gethostbyname
gethostbyaddr
/etc/protocols檔案 配置系統支援的協議
/etc/services檔案 配置服務
get***by***;
gethostbyname
getprotobyname
#include <stdio.h>
#include <netdb.h>
main()
{
struct hostent *ent;
/*開啟主機配置資料庫檔案*/
sethostent(1);
while(1)
{
ent=gethostent();
if(ent==0) break;
printf("主機名:%s\t",ent->h_name);
printf("IP地址:%hhu.%hhu.%hhu.%hhu\t",
ent->h_addr[0],
ent->h_addr[1],
ent->h_addr[2],
ent->h_addr[3]);
printf("別名:%s\n",ent->h_aliases[0]);
}
endhostent();
}
#include <stdio.h>
#include <netdb.h>
main()
{
struct hostent *ent;
ent=gethostbyname("bbs.tarena.com.cn");
//printf("%s\n",ent->h_aliases[0]); printf("%hhu.%hhu.%hhu.%hhu\n",
ent->h_addr_list[0][0],
ent->h_addr_list[0][1],
ent->h_addr_list[0][2],
ent->h_addr_list[0][3]);
}
#include <stdio.h>
#include <netdb.h>
#include <sys/utsname.h>
main()
{
struct protoent *ent;
struct utsname name;
ent=getprotobyname("tcp");
printf("%d\n",ent->p_proto);
uname(&name);
printf("%s\n",name.machine);
printf("%s\n",name.nodename);
printf("%s\n",name.sysname);
printf("%s\n",name.domainname);
}2.TCP/UDP程式設計
對等模型:AF_INET SOCK_DGRAM 0:UDP
C/S 模型:AF_INET SOCK_STREAM 0:TCP
2.0.網路程式設計
ISO的7層模型:
物理層
資料鏈路層 資料鏈路層(資料物理怎麼傳輸)
網路層 IP層 (資料的傳輸方式)
傳輸層 傳輸層 (資料傳輸的結果)
會話層 應用層 (資料傳遞的含義)
表示層
應用層
2.1.UDP程式設計的資料特點
UDP採用對等模型SOCK_DGRAM
socket socket:socket
繫結IP地址bind 連線目標(可選) conncect
read/recv/recvfrom 傳送資料 write/send/sendto
關閉close
案例:
A: B
接收使用者的資料 傳送資料
列印資料與傳送者IP 接收資料並列印
返發一個資訊
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
main()
{
int fd;//socket描述符號 struct sockaddr_in ad;//本機的IP地址 char buf[100];//接收資料緩衝
struct sockaddr_in ad_snd;//傳送者IP地址 socklen_t len;//傳送者IP的長度 int r;
fd=socket(AF_INET,SOCK_DGRAM,17);
if(fd==-1) printf("socket:%m\n"),exit(-1);
printf("建立socket成功!\n");
ad.sin_family=AF_INET;
ad.sin_port=htons(11111);
inet_aton("192.168.180.92",&ad.sin_addr);
r=bind(fd,(struct sockaddr*)&ad,sizeof(ad));
if(r==-1) printf("bind err:%m\n"),exit(-1);
printf("繫結成功!\n");
while(1)
{
len=sizeof(ad_snd);
r=recvfrom(fd,buf,sizeof(buf)-1,0,
(struct sockaddr*)&ad_snd,&len);
if(r>0){
buf[r]=0;
printf("傳送者IP:%s,埠:%hu,資料:%s\n",
inet_ntoa(ad_snd.sin_addr),
ntohs(ad_snd.sin_port),buf);
sendto(fd,"古怪!",strlen("古怪!"),0,
(struct sockaddr*)&ad_snd,sizeof(ad_snd));
}
if(r==0)
{
printf("關閉!\n");
break;
}
if(r==-1)
{
printf("網路故障!\n");
break;
}
}
close(fd);
} 總結:
1.問題:
connect + send == sendto
2.問題:
recvfrom的作用不是專門從指定IP接收
而是從任意IP接收資料,返回傳送資料者的IP
3.問題:
為什麼要bind,bind主要目的告訴網路傳送資料的目標.
是否一定繫結才能傳送資料?
否:只要知道你的IP與PORT,就能傳送資料.
4.問題:
為什麼傳送者沒有繫結IP與埠,他也有埠?
底層網路驅動,幫我們自動生成IP與埠.
5.缺陷:
接收方不區分發送者的.
send函式
sendto函式
int sendto(
int fd,//socket描述符號 const void *buf,//傳送的資料緩衝 size_t size,//傳送的資料長度 int flags,//傳送方式MSG_NOWAIT MSG_OOB const struct sockaddr *addr,//傳送的目標的IP與埠 socklen_t len//sockaddr_in的長度 ); 返回:
-1:傳送失敗
>=0:傳送的資料長度
recv函式
recvfrom函式
int recvfrom(
int fd,
void *buf,
size_t size,
int flags,
struct sockaddr*addr,//返回傳送者IP與埠 socklen_t *len);//輸入返回IP的緩衝大小,返回實際IP的大小 2.2.TCP程式設計的資料特點
2.3.TCP伺服器的程式設計
3.TCP的伺服器程式設計模型
4.IP協議與處理(SOCK_RAW,SOCK_PACKET)
5.pcap程式設計
6.HTTP協議與網頁搜尋
作業:
1.重新編寫UDP網路通訊
2.使用gethostbyname的得到bbs.tarena.com.cn
{
int sem_num;//下標 int sem_op;
int sem_flg;//建議為0.}一.訊號量(同步)
1.回顧:
一個程序控制另外一個程序.
邏輯變數+pause/sleep+訊號
2.訊號量(semaphore)訊號燈
三個資料:紅燈/綠燈/黃燈
60 90 10
訊號量是共享記憶體整數陣列.根據需要定義指定的陣列長度
訊號量就是根據陣列中的值,決定阻塞還是解除阻塞
3.程式設計
3.1.建立或者得到訊號量 semget
3.2.初始化訊號量中指定下標的值 semctl
3.3.根據訊號量阻塞或者解除阻塞 semop
3.4.刪除訊號量 semctl
案例:
A: B
建立訊號量 得到訊號量
初始化訊號量
根據訊號量阻塞 解除阻塞
刪除訊號量
semget函式說明
int semget(key_t key,
int nums,//訊號量陣列個數 int flags);//訊號量的建立標記
//建立IPC_CREAT|IPC_EXCL|0666
//開啟0 返回: -1:失敗
>=0:成功返回訊號量的ID
int semop(
int semid,//訊號量ID struct sembuf *op,//對訊號量的操作.操作可以是陣列多個 size_t nums,//第二個引數的個數 ); 返回:
-1:時失敗
0:成功
int semctl(int semid,
int nums,//對IPC_RMID無意義 int cmd,//SETVAL IPC_RMID );//對IPC_RMID無意義 sem_op:
前提條件訊號量是unsigned short int;
不能<0.
-:夠減,則semop馬上返回,不夠減,則阻塞.
+:執行+操作
0:判定訊號量>0,則阻塞,直到為0
控制程序的搭配方式:
+(解除阻塞) -(阻塞)
0(阻塞) -(解除阻塞)#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//2.1.定義一個聯合體union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
main()
{
key_t key;
int semid; //訊號量ID union semun v;//2.2.定義初始化值 int r;
struct sembuf op[1];
//1.建立訊號量 key=ftok(".",99);
if(key==-1) printf("ftok err:%m\n"),exit(-1);
//semid=semget(key,1/*訊號量陣列個數*/,
// IPC_CREAT|IPC_EXCL|0666);
semid=semget(key,1,0);//得到訊號量 if(semid==-1) printf("get err:%m\n"),exit(-1);
printf("id:%d\n",semid);
//2.初始化訊號量 v.val=2;
r=semctl(semid,0,SETVAL,v);//2.3設定訊號量的值 if(r==-1) printf("初始化失敗!\n"),exit(-1);
//3.對訊號量進行阻塞操作
//3.1.定義操作 op[0].sem_num=0;//訊號量下標 op[0].sem_op=-1;//訊號量操作單位與型別 op[0].sem_flg=0;
while(1)
{
r=semop(semid,op,1);
printf("解除阻塞!\n");
}
//4.刪除(可以不刪除)}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/sem.h>
//2.1.定義一個聯合體union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
main()
{
key_t key;
int semid; //訊號量ID union semun v;//2.2.定義初始化值 int r;
struct sembuf op[2];
//1.建立訊號量 key=ftok(".",99);
if(key==-1) printf("ftok err:%m\n"),exit(-1);
semid=semget(key,1,0);//得到訊號量 if(semid==-1) printf("get err:%m\n"),exit(-1);
printf("id:%d\n",semid);
//3.對訊號量進行阻塞操作
//3.1.定義操作 op[0].sem_num=0;//訊號量下標 op[0].sem_op=1;//訊號量操作單位與型別 op[0].sem_flg=0;
op[1].sem_num=0;//訊號量下標 op[1].sem_op=1;//訊號量操作單位與型別 op[1].sem_flg=0;
while(1)
{
r=semop(semid,op,2);
sleep(1);
}
//4.刪除(可以不刪除)
//semctl(semid,0,IPC_RMID);}
二.網路
1.基礎(ip)
1.1.網路工具
ping
ping ip地址
ping -b ip廣播地址
ifconfig -a
netstat -a
netstat -u
netstat -t
netstat -x
netstat -n
route
lsof
1.2.網路的基本概念
網路程式設計採用socket模型.
網路通訊本質也是程序之間的IPC。
是不同主機之間。
識別主機:4位元組整數:IP地址
識別程序:2位元組整數:埠號
IP地址的表示方法: 內部表示:4位元組整數
外部表示:數點字串
結構體
1 2 3 4 分段表示,每個段使用.分割
"192.168.0.26"
ip地址的轉換:
struct sockaddr_in{
int sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
} struct in_addr
{
in_addr_t s_addr;
} //總結:
IP地址的表示
字串表示"192.168.0.26"
整數表示:in_addr_t;
字結構表示struct in_addr;
連線點:endpoint
struct sockaddr_in
{
in_port_t sin_port;
struct in_addr sin_addr;
}; 1.3.IP地址的轉換
inet_addr //把字串IP轉換為二進位制整數IP(網路位元組序)
inet_aton //把字串IP轉換為struct in_addr;(網路字結序)
#inet_network//把字串IP轉換為二進位制整數IP(本地位元組序)
inet_ntoa //把結構體struct in_addr轉換為字串IP
4個本地主機位元組序與網路序轉換函式:
h表示主機位元組序,n表示網路位元組序,s表示兩個2位元組,l表示4個位元組
uint16_thtons(uint16_t)
uint32_thtonl(uint32_t)
uint16_tntohs(uint16_t)
uint32_tntohl(uint32_t)
ps:所以傳送時候,埠轉換可以用htons,而ip可以用htonl
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
main()
{
/*
in_addr_t nip=192<<24 | 168 <<16 | 0<<8 | 26;
char *ip="192.168.0.26";
//把整數轉換為字串inet_ntoa
struct in_addr sip;
int myip;
sip.s_addr=nip;
printf("nip:%u\n",nip);
printf("%s\n",inet_ntoa(sip));
myip=inet_addr(ip);
printf("%u\n",myip);
printf("%hhu.%hhu.%hhu.%hhu\n", myip>>24 & 255,
myip>>16 & 255,
myip>>8 & 255,
myip>>0 & 255);
*/
/*
char ip[4]={192,168,0,26};
printf("%d\n",*(int*)ip);
*/
char *ip="10.45.8.1";
struct in_addr addr;
in_addr_t net;
in_addr_t host;
struct in_addr tmp;
inet_aton(ip,&addr);
net=inet_lnaof(addr);
host=inet_netof(addr);
tmp.s_addr=net;
printf("%s\n",inet_ntoa(tmp));
tmp.s_addr=host;
printf("%s\n",inet_ntoa(tmp));
}1.4.IP地址的意義
IP地址的位表達不同意義:
IP地址組建網路:網路標識/主機標識
網路 主機
A類 7 24 網路少 主機
B類 14 16
C類 21 8
D類 組播
E類 沒有使用
1.5.計算機系統中的網路配置
/etc/hosts檔案 配置IP,域名,主機名
gethostbyname
gethostbyaddr
/etc/protocols檔案 配置系統支援的協議
/etc/services檔案 配置服務
get***by***;
gethostbyname
getprotobyname
#include <stdio.h>
#include <netdb.h>
main()
{
struct hostent *ent;
/*開啟主機配置資料庫檔案*/
sethostent(1);
while(1)
{
ent=gethostent();
if(ent==0) break;
printf("主機名:%s\t",ent->h_name);
printf("IP地址:%hhu.%hhu.%hhu.%hhu\t",
ent->h_addr[0],
ent->h_addr[1],
ent->h_addr[2],
ent->h_addr[3]);
printf("別名:%s\n",ent->h_aliases[0]);
}
endhostent();
}
#include <stdio.h>
#include <netdb.h>
main()
{
struct hostent *ent;
ent=gethostbyname("bbs.tarena.com.cn");
//printf("%s\n",ent->h_aliases[0]); printf("%hhu.%hhu.%hhu.%hhu\n",
ent->h_addr_list[0][0],
ent->h_addr_list[0][1],
ent->h_addr_list[0][2],
ent->h_addr_list[0][3]);
}
#include <stdio.h>
#include <netdb.h>
#include <sys/utsname.h>
main()
{
struct protoent *ent;
struct utsname name;
ent=getprotobyname("tcp");
printf("%d\n",ent->p_proto);
uname(&name);
printf("%s\n",name.machine);
printf("%s\n",name.nodename);
printf("%s\n",name.sysname);
printf("%s\n",name.domainname);
}2.TCP/UDP程式設計
對等模型:AF_INET SOCK_DGRAM 0:UDP
C/S 模型:AF_INET SOCK_STREAM 0:TCP
2.0.網路程式設計
ISO的7層模型:
物理層
資料鏈路層 資料鏈路層(資料物理怎麼傳輸)
網路層 IP層 (資料的傳輸方式)
傳輸層 傳輸層 (資料傳輸的結果)
會話層 應用層 (資料傳遞的含義)
表示層
應用層
2.1.UDP程式設計的資料特點
UDP採用對等模型SOCK_DGRAM
socket socket:socket
繫結IP地址bind 連線目標(可選) conncect
read/recv/recvfrom 傳送資料 write/send/sendto
關閉close
案例:
A: B
接收使用者的資料 傳送資料
列印資料與傳送者IP 接收資料並列印
返發一個資訊
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
main()
{
int fd;//socket描述符號 struct sockaddr_in ad;//本機的IP地址 char buf[100];//接收資料緩衝
struct sockaddr_in ad_snd;//傳送者IP地址 socklen_t len;//傳送者IP的長度 int r;
fd=socket(AF_INET,SOCK_DGRAM,17);
if(fd==-1) printf("socket:%m\n"),exit(-1);
printf("建立socket成功!\n");
ad.sin_family=AF_INET;
ad.sin_port=htons(11111);
inet_aton("192.168.180.92",&ad.sin_addr);
r=bind(fd,(struct sockaddr*)&ad,sizeof(ad));
if(r==-1) printf("bind err:%m\n"),exit(-1);
printf("繫結成功!\n");
while(1)
{
len=sizeof(ad_snd);
r=recvfrom(fd,buf,sizeof(buf)-1,0,
(struct sockaddr*)&ad_snd,&len);
if(r>0){
buf[r]=0;
printf("傳送者IP:%s,埠:%hu,資料:%s\n",
inet_ntoa(ad_snd.sin_addr),
ntohs(ad_snd.sin_port),buf);
sendto(fd,"古怪!",strlen("古怪!"),0,
(struct sockaddr*)&ad_snd,sizeof(ad_snd));
}
if(r==0)
{
printf("關閉!\n");
break;
}
if(r==-1)
{
printf("網路故障!\n");
break;
}
}
close(fd);
} 總結:
1.問題:
connect + send == sendto
2.問題:
recvfrom的作用不是專門從指定IP接收
而是從任意IP接收資料,返回傳送資料者的IP
3.問題:
為什麼要bind,bind主要目的告訴網路傳送資料的目標.
是否一定繫結才能傳送資料?
否:只要知道你的IP與PORT,就能傳送資料.
4.問題:
為什麼傳送者沒有繫結IP與埠,他也有埠?
底層網路驅動,幫我們自動生成IP與埠.
5.缺陷:
接收方不區分發送者的.
send函式
sendto函式
int sendto(
int fd,//socket描述符號 const void *buf,//傳送的資料緩衝 size_t size,//傳送的資料長度 int flags,//傳送方式MSG_NOWAIT MSG_OOB const struct sockaddr *addr,//傳送的目標的IP與埠 socklen_t len//sockaddr_in的長度 ); 返回:
-1:傳送失敗
>=0:傳送的資料長度
recv函式
recvfrom函式
int recvfrom(
int fd,
void *buf,
size_t size,
int flags,
struct sockaddr*addr,//返回傳送者IP與埠 socklen_t *len);//輸入返回IP的緩衝大小,返回實際IP的大小 2.2.TCP程式設計的資料特點
2.3.TCP伺服器的程式設計
3.TCP的伺服器程式設計模型
4.IP協議與處理(SOCK_RAW,SOCK_PACKET)
5.pcap程式設計
6.HTTP協議與網頁搜尋
作業:
1.重新編寫UDP網路通訊
2.使用gethostbyname的得到bbs.tarena.com.cn