[socket編程-實例]

服務(wù)器端

步驟

  1. 創(chuàng)建一個socket套接字文件描述符
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  2. 創(chuàng)建一個sockaddr_in結(jié)構(gòu)體的變量,并配置相應(yīng)的參數(shù),然后綁定
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr)); //先清除變量值
    serv_addr.sin_family = AF_INET; //表示使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //IP地址
    serv_addr.sin_port = htons(1234); //配置通信端口
    bind(serv_sock, (struct sockaddr)serv_addr, sizeof(serv_addr)); //綁定
    知識點(diǎn):
    a. AF_INET:表示使用IPv4的IP地址,IPv4的IP地址用
    AF_INET6*
    b. inet_addr()函數(shù):將一個點(diǎn)分十進(jìn)制IP地址轉(zhuǎn)換為長整型(unsigned long)的變量,127.0.0.1表示本機(jī)地址
    c. hton()函數(shù):將整型變量從主機(jī)字節(jié)順序轉(zhuǎn)變成網(wǎng)絡(luò)字節(jié)順序(高位字節(jié)存放在內(nèi)存的低地址處。)
    d. bind:將套接字serv_sock與IP地址和端口綁定在一起(存儲在serv_addr中)
  3. 進(jìn)入監(jiān)聽狀態(tài),等待用戶發(fā)送請求
    listen(serv_sock, 20); //對serv_sock套接字進(jìn)行監(jiān)聽,20表示最大允許20個用戶請求排隊
    讓套接字處于被動監(jiān)聽狀態(tài)。所謂被動監(jiān)聽,是指套接字一直處于“睡眠”中,直到客戶端發(fā)起請求才會被“喚醒”
  4. 接收客戶端請求
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(serv_sock, (struct sockaddr*)clnt_addr, &clnt_addr_size);
    用來接收客戶端的請求。程序一旦執(zhí)行到 accept() 就會被阻塞(暫停運(yùn)行),直到客戶端發(fā)起請求。
  5. 向客戶端發(fā)送數(shù)據(jù)
    char str[] = "Hello World!";
    write(clnt_sock, str, sizeof(str));
  6. 關(guān)閉套接字
    close(clnt_sock);
    close(serv_sock);

完整的服務(wù)端socket代碼如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(){
    //創(chuàng)建套接字
    int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    //將套接字和IP、端口綁定
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每個字節(jié)都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具體的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

    //進(jìn)入監(jiān)聽狀態(tài),等待用戶發(fā)起請求
    listen(serv_sock, 20);

    //接收客戶端請求
    struct sockaddr_in clnt_addr;
    socklen_t clnt_addr_size = sizeof(clnt_addr);
    int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);

    //向客戶端發(fā)送數(shù)據(jù)
    char str[] = "Hello World!";
    write(clnt_sock, str, sizeof(str));
   
    //關(guān)閉套接字
    close(clnt_sock);
    close(serv_sock);
    return 0;
}

客戶端

步驟

  1. 創(chuàng)建一個套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
  2. 創(chuàng)建需要連接的服務(wù)器的sockaddr_in結(jié)構(gòu)體的變量,并配置相應(yīng)的參數(shù),然后連接
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr)); //每個字節(jié)都用0填充
    serv_addr.sin_family = AF_INET; //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //因為我們連接的服務(wù)器端在本機(jī)上,所以該地址為本機(jī)地址
    serv_addr.sin_port = htons(1234); //端口
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    注:connect向服務(wù)器發(fā)起請求,服務(wù)器的IP地址和端口號保存在 sockaddr_in 結(jié)構(gòu)體中。直到服務(wù)器端返回數(shù)據(jù),connect才結(jié)束。
  3. 讀取服務(wù)器端返回的數(shù)據(jù)
    char bufRecv[100] = {0};
    read(sock, bufRecv, 100);
    printf("Message form server: %s\n", bufRecv);
  4. 關(guān)閉套接字
    close(sock);

完成的代碼如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(){
    //創(chuàng)建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);

    //向服務(wù)器(特定的IP和端口)發(fā)起請求
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每個字節(jié)都用0填充
    serv_addr.sin_family = AF_INET;            //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具體的IP地址
    serv_addr.sin_port = htons(1234);  //端口
    connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
   
    //讀取服務(wù)器傳回的數(shù)據(jù)
    char buffer[40];
    read(sock, buffer, sizeof(buffer)-1);
    printf("Message form server: %s\n", buffer);
   
    //關(guān)閉套接字
    close(sock);
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 一、基本socket函數(shù)Linux系統(tǒng)是通過提供套接字(socket)來進(jìn)行網(wǎng)絡(luò)編程的。網(wǎng)絡(luò)的socket數(shù)據(jù)傳輸...
    WB莫遙燚閱讀 1,498評論 0 0
  • 套接字是網(wǎng)絡(luò)通信的基石,是網(wǎng)絡(luò)通信的基本構(gòu)建,最初是由加利福利亞大學(xué)Berkeley分校為UNIX開發(fā)的網(wǎng)絡(luò)通信編...
    Super超人閱讀 4,365評論 0 26
  • 下面為Daytime這個服務(wù)的源代碼例子,同時兼容IPV6和IPV4的地址,最后部分有更多說明。 單播模式下的Se...
    天楚銳齒閱讀 5,780評論 0 2
  • 大綱 一.Socket簡介 二.BSD Socket編程準(zhǔn)備 1.地址 2.端口 3.網(wǎng)絡(luò)字節(jié)序 4.半相關(guān)與全相...
    VD2012閱讀 2,454評論 0 5
  • socket通信原理 socket又被叫做套接字,它就像連接到兩端的插座孔一樣,通過建立管道,將兩個不同的進(jìn)程之間...
    jiodg45閱讀 1,187評論 0 1