tcp套介面程式設計(socket)
socket起源於unix,而unix/linux基本哲學之一就是「一切皆檔案」,都可以用「開啟open –> 讀寫write/read –> 關閉close」模式來操作。我的理解就是socket就是該模式的乙個實現,socket即是一種特殊的檔案,一些socket函式就是對其進行的操作(讀/寫io、開啟、關閉)。
1.套介面的資料結構。在標頭檔案中,其資料結構定義如下
struct sockaddr
struct socketaddr_in
;
以上是通用的套介面的資料結構,在平常中我們用到的是ipv4套介面的位址資料結構。
在tcp套介面程式設計中。server端和client端相互通訊,其步驟如下:
上面是基本的socket程式設計,通訊模型。
1. server.c
#include #include #include #include #include #include #include #include #include #define maxsize 1024 /*定義資料緩衝區大小*/
int main(int argc, char *argv)
; // 傳送快取區大小
if( argc != 2)
portno = atoi(argv[1]); // 引數二的埠
// 第一步建立套介面
sock_fd = socket(af_inet, sock_stream, 0);
if (sock_fd == -1)
else fprintf(stdout, "create socket success.\n");
// 第二步填充套接字
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = af_inet;
server_addr.sin_addr.s_addr = htonl(inaddr_any);
server_addr.sin_port = htons(portno);
ret = bind(sock_fd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr));
if (ret == -1)
else fprintf(stdout, "bind port success.\n");
// 第三步監聽客戶端的請求,最大請求數為5
if( listen(sock_fd, 5) == -1)
else fprintf(stdout, "listen success.\n");
// 第四步接收請求accept()
while (1) // 服務端採用阻塞模式,等待客戶端請求
printf("connected sucessful, please enter reply message: ");
fgets(buffer, maxsize, stdin);
if( write(new_fd, buffer, strlen(buffer)) == -1)
close(new_fd); // 本次通訊接收,關閉客戶端的套介面,等待接收下次
usleep(30000);
} close(sock_fd); // 服務端程序終止,關閉服務端套介面
return 0;
}
2. client.c
#include #include #include #include #include #include #include #include #define maxsize 1024
int main(int argc, char *argv)
; struct sockaddr_in server_addr;
struct hostent *host = null;
int portno, nbytes;
if (argc != 3)
if (argv[1][1] == 'h')
host = gethostbyname(argv[1]+2);
else if (argv[1][1] == 'a')
; int sta = inet_pton(af_inet, argv[1] + 2, ipaddr);
printf("%s %s ipaddr: %s\n", argv[1] + 2, argv[2] + 2, ipaddr);
if (sta == 0)
else if(sta == -1)
host = gethostbyaddr(ipaddr, sizeof(struct in_addr), af_inet);
} if (host == null)
else fprintf(stdout, "get host success.\n");
// 第一步建立客戶端套接字
sock_fd = socket(af_inet, sock_stream, 0);
if (sock_fd == -1)
else fprintf(stdout, "create socket success.\n");
portno = atoi(argv[2] + 2);
// 第二步填充套接字
bzero(&server_addr, sizeof(struct sockaddr));
server_addr.sin_family = af_inet;
server_addr.sin_addr = *((struct in_addr *)(host->h_addr));
server_addr.sin_port = htons(portno);
// 第四步connect服務端
ret = connect(sock_fd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr));
if (ret == -1)
else fprintf(stdout, "connected server success.\n");
// 第五步鏈結成功後,讀取服務端的資料
nbytes = read(sock_fd, buffer, maxsize);
fprintf(stdout,"client received msg(tcp): %s\n", buffer);
// 客戶端受到服務端的資料後,關閉服務端套介面,結束通訊
close(sock_fd);
return 0;
}
注意:當執行測試時,可能出現問題,情況很多如防火牆,位址不對,主機找不到,埠被占用等等,這些問題都要確保解決後,方能執行成功。 基本TCP套介面的程式設計流程
要實現客戶端和伺服器端的通訊,則需要客戶端和伺服器端共同完成。其中,tcp伺服器和客戶端的程式設計流程如圖所示 首先由伺服器端建立socket,然後bind繫結通訊埠,建立listen監聽佇列。之後便開始了通訊的過程。此時伺服器阻塞在accept這裡,直到tcp客戶端主動進行connect進行三次握...
套介面程式設計
1 struct in addr 4struct sockaddr in 通用套介面位址結構 struct sockaddr int bind int struct sockaddr socklen t strcut sockaddr in serv bind sockfd,struct socka...
套介面程式設計
1 struct in addr 4struct sockaddr in struct sockaddr int bind int struct sockaddr socklen t strcut sockaddr in serv bind sockfd,struct sockaddr serv,s...