1.TCP/IP簡介
TCP/IP協議源于1969年,是針對Internet開發的一種體系結構和協議標準,目的在于解決異種計算機網絡的通信問題。使得網絡在互聯時能為用戶提供一種通用、一致的通信服務。是Internet采用的協議標準。
TCP/IP是一組通信協議的代名詞,是由一系列協議組成的協議簇。它本身指兩個協議集:
TCP(傳輸控制協議)。
? IP(互聯網絡協議)。
TCP/IP協議的基本傳輸單位是數據包(Datagram)。
TCP/IP傳輸協議,即傳輸控制/網絡協議,也叫作網絡通訊協議。它是在網絡的使用中的最基本的通信協議。TCP/IP傳輸協議對互聯網中各部分進行通信的標準和方法進行了規定。并且,TCP/IP傳輸協議是保證網絡數據信息及時、完整傳輸的兩個重要的協議。TCP/IP傳輸協議是嚴格來說是一個四層的體系結構,應用層、傳輸層、網絡層和數據鏈路層都包含其中。
2.獲取本地網卡信息
??獲取本地網卡信息的方法有很多種,在Linux命令行下我們可以通過ifconfig命令查詢網卡信息。
2.1 通過ioctl函數獲取網卡信息
??ioctl(input/output control)是一個專用于設備輸入輸出操作的系統調用,該調用傳入一個跟設備有關的請求碼,系統調用的功能完全取決于請求碼。
- ioctl函數原型:
#include
int ioctl(int fd, unsigned long request, ...);
形參:fd --文件描述符
request --請求命令
第三個參數為可變參數,該參數填寫取決于request 命令;
返回值:一般成功返回0
網絡相關的請求劃分為6 類:
- 套接口操作
- 文件操作
- 接口操作
- ARP 高速緩存操作
- 路由表操作
- 流系統
下表列出了網絡相關ioctl 請求的request 參數以及arg 地址必須指向的數據類型:
獲取網卡信息示例:
#include
#include
#include
#include
#include
#include
#include
#include
int main()
{
int i=0;
int sockfd;
/*創建網絡套接字*/
if((sockfd = socket(AF_INET, SOCK_STREAM,0))0)
{
printf("socket errorn");
return -1;
}
struct ifreq ifcu_req[4];//網卡信息結構體
struct ifconf ifc=
{
.ifc_len=sizeof(ifcu_req),//緩沖區大小
.ifc_req=ifcu_req,
};
struct ifreq b_addr;
int ret=ioctl(sockfd,SIOCGIFCONF, &ifc);//獲取網絡接口信息
struct sockaddr boardaddr;
struct sockaddr_in addr;
printf("ret=%dn",ret);
char mac[6];
int j=0;
int count=ifc.ifc_len/sizeof(struct ifreq);//計算獲取到的網卡信息個數
for(i=0;i
3.域名解析
域名(英語:Domain Name),又稱網域,是由一串用點分隔的名字組成的Internet上某一臺計算機或計算機組的名稱,用于在數據傳輸時對計算機的定位標識(有時也指地理位置)。
由于IP地址具有不方便記憶并且不能顯示地址組織的名稱和性質等缺點,人們設計出了域名,并通過網域名稱系統(DNS,Domain Name System)來將域名和IP地址相互映射,使人更方便地訪問互聯網,而不用去記住能夠被機器直接讀取的IP地址數串。
#include
extern int h_errno;
struct hostent *gethostbyname(const char *name);
函數功能:域名解析
形參:name --域名
返回值:
struct hostent {
char *h_name; /* 主機的正式名稱 */
char **h_aliases; /* 別名列表*/
int h_addrtype; /* 主機地址類型*/
int h_length; /* 地址長度*/
char **h_addr_list; /*地址列表 */
}
void herror(const char *s); //錯誤輸出
const char *hstrerror(int err);//根據錯誤編號返回錯誤消息字符串
示例
#include
#include
#include
#include
#include
#include
int main(int argc,char *argv[])
{
if(argc!=2)
{
printf("格式:./app n");
return 0;
}
//域名解析
struct hostent *host_info=gethostbyname(argv[1]);
if(host_info==NULL)
{
printf("err=%d,%sn",h_errno,hstrerror(h_errno));
return 0;
}
int i=0;
struct in_addr addr;
printf("主機名:%sn",host_info->h_name);
for(i=0;host_info->h_aliases[i]!=0;i++)
{
printf("主機別名:%sn",host_info->h_aliases[i]);
}
for(i=0;host_info->h_addr_list[i]!=0;i++)
{
memcpy(&addr,host_info->h_addr_list[i],sizeof(addr));
printf("ip地址:%sn",inet_ntoa(addr));
}
}
運行效果:
獲取邦定ip地址信息getsockname
getsockname()函數用于獲取一個套接字的名字。它用于一個已捆綁或已連接套接字,本地地址將被返回。本調用特別適用于如下情況:未調用bind()就調用了connect(),這時唯有getsockname()調用可以獲知系統內定的本地地址。在返回時,namelen參數包含了名字的實際字節數。
#include
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
函數功能:獲取sockfd綁定的ip地址和端口號信息
形 參:sockfd --網絡套接字
addr --保存返回的ip地址和端口號信息
addrlen --addr緩沖區大小(必須由用戶設置大小,函數調用成功返回實際addr大小)
返回值:成功返回0,失敗-1
示例:
#include
#include /* See NOTES */
#include
#include
#include
#include
#include /* superset of previous */
#include
int main(int argc,char *argv[])
{
if(argc!=3)
{
printf("格式:./app n");
return 0;
}
/*創建網絡套接字*/
int sockfd=socket(AF_INET, SOCK_STREAM,0);
if(sockfd==-1)
{
printf("創建網絡套接字失敗n");
return 0;
}
/*連接服務器*/
struct sockaddr_in addr=
{
.sin_family=AF_INET,//IPV4
.sin_port=htons(atoi(argv[1])),//服務器端口號
.sin_addr=
{
.s_addr=inet_addr(argv[2]),//服務器IP
}
};
if(connect(sockfd,(struct sockaddr *)&addr,sizeof(addr)))
{
printf("連接服務器失敗n");
return 0;
}
printf("服務器連接成功n");
struct sockaddr_in c_addr;
socklen_t addrlen=sizeof(c_addr);
getsockname(sockfd,(struct sockaddr *)&c_addr, &addrlen);
printf("本地信息%s:%dn",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
while(1)
{
}
}
-
嵌入式
+關注
關注
5082文章
19104瀏覽量
304791 -
網卡
+關注
關注
4文章
307瀏覽量
27374 -
編程
+關注
關注
88文章
3614瀏覽量
93685 -
TCP
+關注
關注
8文章
1353瀏覽量
79055
發布評論請先 登錄
相關推薦
評論