欧美1区2区3区激情无套,两个女人互添下身视频在线观看,久久av无码精品人妻系列,久久精品噜噜噜成人,末发育娇小性色xxxx

通過一個(gè)最簡單的例子來看服務(wù)端編程的流程

在了解服務(wù)端編程的流程之前,我們需要先了解幾個(gè)函數(shù):
1.創(chuàng)建套接字的函數(shù)(關(guān)于套接字的介紹在上一節(jié)中有了簡單的描述,其實(shí)就是一個(gè)文件描述符,也就是一個(gè)整數(shù))

首先我們可以在Linux終端輸入:man 7 socket來查看系統(tǒng)對這個(gè)函數(shù)的描述文檔。
圖片說明
從以上描述我們可以看到,你要使用這個(gè)函數(shù),首先要包含sys/socket.h頭文件。
然后可以看到,這個(gè)函數(shù)有三個(gè)參數(shù):
a.第一個(gè)socket_family表示地址族,這個(gè)我們一般用的就是AF_INET,表示ipv4地址族。
b.第二個(gè)參數(shù)socket_type,從名字我們就可以看出來,是套接字的類型,上節(jié)也提到了套接字主要有兩種類型,一種是流格式的套接字(SOCK_STREAM),另一種是數(shù)據(jù)報(bào)格式的套接字(SOCK_DGRAM),分別對應(yīng)TCP協(xié)議和UDP協(xié)議。
c.第三個(gè)參數(shù)協(xié)議,IPPROTO_TCP表示使用的是TCP協(xié)議

調(diào)用這個(gè)函數(shù),用一個(gè)整型接收他的返回值,我們就得到了一個(gè)套接字。

2.bind函數(shù),通過這個(gè)函數(shù)將套接字與IP和端口等進(jìn)行綁定。
同樣我們可以在終端中鍵入:man 2 bind命令來查看相關(guān)文檔
圖片說明
這個(gè)函數(shù)也有三個(gè)參數(shù):
a.第一個(gè)就是我們通過socket函數(shù)得到的套接字,也就是你要綁定的套接字。
b.第二個(gè)就是一個(gè)sockaddr結(jié)構(gòu),我們只需要知道里面有幾個(gè)重要的成員就可以了,比如port addr family 分別表示端口,IP地址,地址族等。
c.第三個(gè)參數(shù)就是第二個(gè)結(jié)構(gòu)的長度。

這個(gè)函數(shù)的返回值表示這個(gè)函數(shù)是否執(zhí)行成功,具體細(xì)節(jié)可以查看man文檔

3.listen函數(shù),這個(gè)函數(shù)就是用來監(jiān)聽套接字的,監(jiān)聽有沒有人來連接你套接字綁定的地址和端口。
同樣man listen查看man文檔
圖片說明
這個(gè)函數(shù)有兩個(gè)參數(shù):
a.第一個(gè)參數(shù)是我們通過socket函數(shù)拿到的套接字
b.第二個(gè)參數(shù)表示能連接到這個(gè)套接字的最大數(shù)值。可以自己設(shè)定

4.accept函數(shù),這個(gè)函數(shù)用來接收客戶端連接請求
man accept查看man文檔
圖片說明
三個(gè)參數(shù):
a.第一個(gè)是服務(wù)端的套接字
b.第二個(gè)要注意,這次是客戶端的sockaddr結(jié)構(gòu),它是一個(gè)傳出參數(shù),也就是你傳一個(gè)這種結(jié)構(gòu)的地址進(jìn)去,函數(shù)調(diào)用結(jié)束之后,這個(gè)結(jié)構(gòu)就被賦值了。你就可以拿來用了。
c.第三個(gè)參數(shù)是第二個(gè)參數(shù)結(jié)構(gòu)的長度

它的返回值也要注意,它返回的是連接服務(wù)器的客戶端的套接字,我們可以用一個(gè)整型來進(jìn)行接收,我們之前說過,套接字其實(shí)就是一個(gè)文件描述符,我們得到了這個(gè)文件描述符之后,就可以對這個(gè)描述符進(jìn)行文件操作了,比如給它寫幾個(gè)數(shù)據(jù),就相當(dāng)于給客戶端發(fā)送了數(shù)據(jù)。

接下來是服務(wù)端的代碼:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main()
{
    //創(chuàng)建一個(gè)套接字,服務(wù)端
    int sock_serv = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    //AF_INET表示的是ipv4地址族,
    //第二個(gè)參數(shù)SOCK_STREAM表示的是套接字類型:流格式的套接字,第三個(gè)參數(shù)表示使用的協(xié)議是TCP

    //將套接字和IP、端口等綁定
    struct sockaddr_in sockaddr_serv;
    memset(&sockaddr_serv, 0, sizeof(sockaddr_serv));
    sockaddr_serv.sin_family = AF_INET;
    sockaddr_serv.sin_port = htons(1234);
    sockaddr_serv.sin_addr.s_addr = inet_addr("127.0.0.1");
    //這個(gè)函數(shù)的第一個(gè)參數(shù)是套接字(整型),第二個(gè)參數(shù)是用來初始化端口和IP的結(jié)構(gòu)(注意要進(jìn)行強(qiáng)制轉(zhuǎn)換),第三參數(shù)就是結(jié)構(gòu)的大小了
    bind(sock_serv, (struct sockaddr*)&sockaddr_serv, sizeof(sockaddr_serv));

    //監(jiān)聽套接字,看網(wǎng)絡(luò)上有多少個(gè)主機(jī)會來和這個(gè)套接字進(jìn)行連接
    listen(sock_serv, 20); //第二個(gè)參數(shù)是能連接這個(gè)套接字的最大數(shù)量

    //接收客戶端請求
    struct sockaddr_in sockaddr_client;
    socklen_t socklen_client = sizeof(sockaddr_client);
    int sock_client = accept(sock_serv, (struct sockaddr*)&sockaddr_client, &socklen_client);
    //accept的第三個(gè)參數(shù)是傳出參數(shù),也就是把這個(gè)參數(shù)傳給函數(shù)accept函數(shù)之后,函數(shù)會對這個(gè)參數(shù)進(jìn)行賦值,函數(shù)調(diào)用完之后
    //這個(gè)參數(shù)就有值了,可供調(diào)用者使用。


    //向客戶端寫數(shù)據(jù)
    char str[] = "I am a boy!";
    write(sock_client, str, sizeof(str));

    //最后要記得關(guān)掉套接字,也就是要關(guān)掉文件描述符
    close(sock_serv);
    close(sock_client);

    return 0;
}

上面的代碼中,我們給服務(wù)端sockaddr結(jié)構(gòu)賦值的時(shí)候用的是sockaddr_in,所以在賦完值之后準(zhǔn)備傳給bind函數(shù)時(shí)要進(jìn)行強(qiáng)制轉(zhuǎn)換。這里的服務(wù)端IP用的是本地回環(huán)測試IP 127.0.0.1 也就是把本機(jī)當(dāng)作服務(wù)器。

然后就是客戶端:
客戶端我們要了解一個(gè)函數(shù)connect:
從這個(gè)函數(shù)名我們都可以知道,這是用來連接服務(wù)器的函數(shù),我們可以想一想,要連接服務(wù)器,我們要如何找到服務(wù)器呢,當(dāng)然是通過IP和端口啦。這個(gè)IP和端口也是通過sockaddr結(jié)構(gòu)來給的。
通過man 2 connect查看man文檔
圖片說明
這個(gè)函數(shù)也有三個(gè)參數(shù):
a.第一個(gè)參數(shù)是客戶端的套接字,客戶端也是需要用socket函數(shù)創(chuàng)建套接字的,因?yàn)榉?wù)端調(diào)用accept函數(shù)得到的是客戶端的套接字,如果服務(wù)器給客戶端寫了數(shù)據(jù),客戶端就可以通過這個(gè)套接字來讀到。
b.第二個(gè)參數(shù)是sockaddr結(jié)構(gòu),注意這個(gè)結(jié)構(gòu)是服務(wù)端的信息。
c.第三個(gè)參數(shù)是第二個(gè)參數(shù)的長度。

下面是客戶端的代碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main()
{
    //客戶端也要?jiǎng)?chuàng)建一個(gè)套接字
    int socket_client = socket(AF_INET, SOCK_STREAM, 0);

    //設(shè)置要連接的服務(wù)器的IP 端口 地址族等
    struct sockaddr_in sockaddr_serv;
    memset(&sockaddr_serv, 0, sizeof(sockaddr_serv));
    sockaddr_serv.sin_addr.s_addr = inet_addr("127.0.0.1");
    sockaddr_serv.sin_family = AF_INET;
    sockaddr_serv.sin_port = htons(1234);
    //客戶端連接服務(wù)器
    connect(socket_client, (struct sockaddr *)&(sockaddr_serv), sizeof(sockaddr_serv));

    //讀取服務(wù)器傳回的數(shù)據(jù)
    char str[50];
    read(socket_client, str, sizeof(str) - 1);
    //回顯到終端輸出
    printf("get the data from server: %s\n", str);

    close(socket_client);

    return 0;
}

要實(shí)現(xiàn)效果我們是要開兩個(gè)終端的,因?yàn)榉?wù)端代碼啟動(dòng)之后是會進(jìn)入阻塞狀態(tài)的,等待客戶端的連接。先啟動(dòng)服務(wù)端,再啟動(dòng)客戶端。

1.啟動(dòng)服務(wù)器
圖片說明
我們可以看到,執(zhí)行服務(wù)端程序之后,程序阻塞了。

2.然后啟動(dòng)客戶端
圖片說明
我們可以看到,服務(wù)端給客戶端寫的數(shù)據(jù),客戶端讀了之后,回顯到終端了。

全部評論

相關(guān)推薦

FieldMatching:看成了豬頭顧問,不好意思
點(diǎn)贊 評論 收藏
分享
評論
點(diǎn)贊
收藏
分享

創(chuàng)作者周榜

更多
??途W(wǎng)
牛客企業(yè)服務(wù)