TCP套介面程式設計 Socket

2021-06-28 08:18:16 字數 3429 閱讀 8555

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...