初識TC套接字

創建套接字:
int sockfd;
if(sockfd=sock(AF_INET,SOCK_STREAM,0)<0)
//err_sys("socket err");如果套接字函數調用失敗,就調用自己的err_sys函數放棄程序執行;
return ;或者直接return 退出程序

指定服務器的IP地址和端口:
struct sockaddr_in  servaddr; 我們把服務器的IP地址和端口填入一個網際套接字地址結構,一個名爲servaddr的sockaddr_in  的結構體變量,使用bzero把整個結構體清零:bzero(&servaddr,sizeof(sercaddr)),設置地址族爲AF_INET,servaddr.sin_family=AF_INET;端口號爲13,seraddr.sin_port=htons(13);13爲時間獲取服務器的常用端口,支持該服務的TCP/IP的主機都使用這個端口;
庫函數 htons(主機到網絡短整數)去轉換二進制端口號,又調用庫函數inet_pton(呈現形式到數值)(支持IPV6)去把ACSII碼命令行參數轉換爲合適的格式。

inet_pton:將“點分十進制” -> “二進制整數”
int inet_pton(int af, const char *src, void *dst);
這個函數轉換字符串到網絡地址,第一個參數af是地址簇,第二個參數*src是來源地址,第三個參數* dst接收轉換後的數據。
inet_pton 是inet_addr的擴展,支持的多地址族有下列:
src爲指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函數將該地址轉換爲in_addr結構體,並複製在*dst中。
af = AF_INET6
src爲指向IPV6的地址,函數將該地址轉換爲in6_addr的結構體,並複製在*dst中。
如果函數出錯將返回一個負值,並將errno設置爲EAFNOSUPPORT,如果參數af指定的地址族和src格式不對,函數將返回0。
下面是例程:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main (void)
{
char IPdotdec[20]; //存放點分十進制IP地址
struct in_addr s; // IPv4地址結構體
// 輸入IP地址
printf("Please input IP address: ");
scanf("%s", IPdotdec);
// 轉換
inet_pton(AF_INET, IPdotdec, (void *)&s);
printf("inet_pton: 0x%x\n", s.s_addr); // 注意得到的字節序
// 反轉換
inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);
printf("inet_ntop: %s\n", IPdotdec);
}

建立與服務器的連接:
if(connect(sockfd,(SOCKADDR*)&servaddr,sizeof(SOCKADDR))<0)
err_sys("connect err");
connect函數應用於TCP套接字時,將與由它的第二個參數指向的套接字地址結構指定的服務器建立一個TCP連接,第三個參數指定該套接字地址結構的長度。

讀入並輸出服務器的應答:
while((n=read(sockfd,recvline,MAXLINE))>0)
{
   recline[n]=0;
 if(fputs(recvline,stdout)==EOF)
  err_sys("fputs err");
}
我們使用read函數讀取服務器的應答,並用標準的I/O函數fputs輸出結果,TCP是一個沒有記錄邊界的字節流協議,服務器的應答通常是如下格式的26個字節字符串,Mon May 26 20:59:40 2003\r\n,通常服務器返回包含所有26個字節的單個分節,但是如果數據量很大,我們就不能保證一次read調用就能返回服務器的整個應答,因此需要把read編寫在某個循環中,當read返回0或者負值時終止循環。

退出程序:
exit(0);
發佈了61 篇原創文章 · 獲贊 7 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章