日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux下的socket演示程序

發布時間:2025/3/12 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下的socket演示程序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

和C語言教程一樣,我們從一個簡單的“Hello World!”程序切入?socket?編程。

本節演示了?Linux?下的代碼,server.cpp 是服務器端代碼,client.cpp 是客戶端代碼,要實現的功能是:客戶端從服務器讀取一個字符串并打印出來。

服務器端代碼 server.cpp:

  • #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(){
  • //創建套接字
  • int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  • ?
  • //將套接字和IP、端口綁定
  • struct sockaddr_in serv_addr;
  • memset(&serv_addr, 0, sizeof(serv_addr));? //每個字節都用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));
  • ?
  • //進入監聽狀態,等待用戶發起請求
  • 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);
  • ?
  • //向客戶端發送數據
  • char str[] = "http://c.biancheng.net/socket/";
  • write(clnt_sock, str, sizeof(str));
  • ?
  • //關閉套接字
  • close(clnt_sock);
  • close(serv_sock);
  • ?
  • return 0;
  • }

  • 客戶端代碼 client.cpp:

  • #include <stdio.h>
  • #include <string.h>
  • #include <stdlib.h>
  • #include <unistd.h>
  • #include <arpa/inet.h>
  • #include <sys/socket.h>
  • ?
  • int main(){
  • //創建套接字
  • int sock = socket(AF_INET, SOCK_STREAM, 0);
  • ?
  • //向服務器(特定的IP和端口)發起請求
  • struct sockaddr_in serv_addr;
  • memset(&serv_addr, 0, sizeof(serv_addr)); //每個字節都用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));
  • ?
  • //讀取服務器傳回的數據
  • char buffer[40];
  • read(sock, buffer, sizeof(buffer)-1);
  • ?
  • printf("Message form server: %s\n", buffer);
  • ?
  • //關閉套接字
  • close(sock);
  • ?
  • return 0;
  • }

  • 啟動一個終端(Shell),先編譯 server.cpp 并運行:

    [admin@localhost ~]$ g++ server.cpp -o server
    [admin@localhost ~]$ ./server
    #等待請求的到來

    正常情況下,程序運行到?accept() 函數就會被阻塞,等待客戶端發起請求。

    接下再啟動一個終端,編譯 client.cpp 并運行:

    [admin@localhost ~]$ g++ client.cpp -o client
    [admin@localhost ~]$ ./client
    Message form server:?http://c.biancheng.net/socket/

    client 接收到從 server發送過來的字符串就運行結束了,同時,server 完成發送字符串的任務也運行結束了。大家可以通過兩個打開的終端來觀察。

    client 運行后,通過 connect() 函數向 server 發起請求,處于監聽狀態的 server 被激活,執行 accept() 函數,接受客戶端的請求,然后執行 write() 函數向 client 傳回數據。client 接收到傳回的數據后,connect() 就運行結束了,然后使用 read() 將數據讀取出來。

    server 只接受一次 client 請求,當 server 向 client 傳回數據后,程序就運行結束了。如果想再次接收到服務器的數據,必須再次運行 server,所以這是一個非常簡陋的 socket 程序,不能夠一直接受客戶端的請求。

    源碼解析

    1) 先說一下 server.cpp 中的代碼。

    第 11 行通過 socket() 函數創建了一個套接字,參數?AF_INET 表示使用 IPv4 地址,SOCK_STREAM 表示使用面向連接的套接字,IPPROTO_TCP 表示使用 TCP 協議。在 Linux 中,socket 也是一種文件,有文件描述符,可以使用 write() / read() 函數進行 I/O 操作,這一點已在《socket是什么》中進行了講解。

    第 19 行通過 bind() 函數將套接字 serv_sock 與特定的 IP 地址和端口綁定,IP 地址和端口都保存在 sockaddr_in 結構體中。

    socket() 函數確定了套接字的各種屬性,bind() 函數讓套接字與特定的IP地址和端口對應起來,這樣客戶端才能連接到該套接字。

    第 22 行讓套接字處于被動監聽狀態。所謂被動監聽,是指套接字一直處于“睡眠”中,直到客戶端發起請求才會被“喚醒”。

    第 27 行的 accept() 函數用來接收客戶端的請求。程序一旦執行到 accept() 就會被阻塞(暫停運行),直到客戶端發起請求。

    第 31 行的 write() 函數用來向套接字文件中寫入數據,也就是向客戶端發送數據。

    和普通文件一樣,socket 在使用完畢后也要用 close() 關閉。

    2) 再說一下 client.cpp 中的代碼。client.cpp 中的代碼和 server.cpp 中有一些區別。

    第 19 行代碼通過 connect() 向服務器發起請求,服務器的IP地址和端口號保存在 sockaddr_in 結構體中。直到服務器傳回數據后,connect() 才運行結束。

    第 23 行代碼通過 read() 從套接字文件中讀取數據。

    總結

    以上是生活随笔為你收集整理的Linux下的socket演示程序的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。