各位看官們,大家好,上1回中我們說的是基于AF_UNIX域的數(shù)據(jù)報套接字通訊的例子,這1回我們說的例子是:基于AF_INET域的流套接字通訊 。閑話休提,言歸正轉。讓我們1起talk C栗子吧!
看官們,我們在上1回中1起制作了我們的第2道佳肴是:基于AF_UNIX域的數(shù)據(jù)報套接字通訊。今天,我將和大家1起制作第3道佳肴:基于AF_INET域的流套接字通訊。
- 制作第3道佳肴的菜譜:流套接字進程。
- 制作第3道佳肴的食材:流套接字的接口,套接字屬性,套接字地址信息。
看官們,以上的內容,我們在前面章回中都詳細介紹過,如果大家忘記的話,可以參考前面的內容,重點是第1百4107回的內容,由于這是我們的菜譜。在食材中最麻煩是套接字地址信息,大家可以參考1百5105回中的例子。多說無益,我們通過具體的代碼來演示。
//1.設置服務器端套接字的屬性:域,類型和協(xié)議,我們使用了getaddrinfo函數(shù);
char * host = "localhost"; //using localhost IP address:127.0.0.1
char * server = "1080"; //using port 1080, it must be more then 1024
struct addrinfo hints;
struct addrinfo *result;
memset(&hints,0,sizeof(struct addrinfo));
result = NULL;
hints.ai_flags = AI_NUMERICSERV;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
//get address info ,it has all attribute of socket
res = getaddrinfo(host,server,&hints,&result);
//2. 創(chuàng)建服務器端套接字
server_fd = socket(result->ai_family,result->ai_socktype,result->ai_protocol);
//3.把服務器真?zhèn)€套接字和服務器的地址綁定在1起
res = bind(server_fd,result->ai_addr,result->ai_addrlen);
//4.創(chuàng)建套接字隊列,為通訊做好準備,開始監(jiān)聽客戶端發(fā)來的通訊連接要求
res = listen(server_fd,2);
//5.接受客戶端發(fā)來的連接要求,并且取得與客戶端匹配的socket
client_fd = accept(server_fd,NULL,NULL);
//6.通過套接字讀取數(shù)據(jù)
res = read(client_fd,buf,BUF_SIZE);
printf("[server] receiving data (%s) from client by socket\n",buf);
//7.釋放套接字,關閉通訊
if(result->ai_next)
freeaddrinfo(result);
res = close(client_fd);
res = close(server_fd);
//1.設置客戶端套接字的屬性:域,類型和協(xié)議;
char * host = "localhost"; //using localhost IP address:127.0.0.1
char * server = "1080"; //using port 1080, it must be more then 1024
struct addrinfo hints;
struct addrinfo *result;
memset(&hints,0,sizeof(struct addrinfo));
result = NULL;
hints.ai_flags = AI_NUMERICSERV;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
//get address info ,it has all attribute of socket
res = getaddrinfo(host,server,&hints,&result);
//2.創(chuàng)建客戶端套接字;
client_fd = socket(result->ai_family,result->ai_socktype,result->ai_protocol);
//3.使用客戶端套接字和服務器進行連接;
res = connect(client_fd,result->ai_addr,result->ai_addrlen);
//4.通過套接字發(fā)送數(shù)據(jù);
printf("[client] sending data (%s )to server by socket \n",buf);
res = write(client_fd,buf,sizeof(buf) );
//5.釋放套接字,斷開客戶端與服務器真?zhèn)€通訊;
if(result->ai_next)
freeaddrinfo(result);
res = close(client_fd);
看官們,以上是核心代碼,完全的代碼放到了我的資源中,大家可以點擊這里下載使用。
關于上面的代碼,我做1些補充說明:
我們需要把服務器真?zhèn)€代碼和客戶真?zhèn)€代碼分別進行編譯,并且編譯成不同的可以履行文件:
$ gcc Ex092_InetStreamSocketClient.c -o client //編譯客戶端
$ gcc Ex092_InetStreamSocketServer.c -o server //編譯服務器端
看官們,美味佳肴做好了,我們1起來品味下,品味方法就是運行程序,下面是程序的運行結果,請大家參考:
$./server & //在后面運行服務器
[1] 4643
$ ./client //運行客戶端
please input less then 8 chars for using.
hello
[client] sending data (hello )to server by socket
[server] receiving data (hello) from client by socket
$ ./client //再次運行客戶端
please input less then 8 chars for using.
stream
[client] sending data (stream )to server by socket
[server] receiving data (stream) from client by socket
[1]+ Done ./server //服務器端運行結束
看官們,從上面的運行結果中可以看到,客戶端通過套接字發(fā)送數(shù)據(jù)給服務器,而服務器通過套接字接收客戶端發(fā)來的數(shù)據(jù),這樣客戶端和服務器端可以通過套接字進行通訊。另外,我們進行了兩次通訊,通訊的次數(shù)可以自己控制,乃至寫成無窮次也是可以的。每次通訊可以看做是1個完全的通訊進程,我們在通訊進程中發(fā)送的數(shù)據(jù)是字符串“hello”和”stream”,大家也能夠發(fā)送其它的字符串。
各位看官,關于基于AF_INET域的流套接字通訊的例子我們就說到這里。欲知后面還有甚么例子,且聽下回分解 。