1. 程式人生 > >Linux網路程式設計(2)簡單的TCP回射伺服器(Echo Server)

Linux網路程式設計(2)簡單的TCP回射伺服器(Echo Server)

先介紹一下TCP伺服器大概的工作流程。首先,和TCP客戶端一樣,需要建立一個套接字,然後必須給套接字繫結一個埠。這一點和TCP客戶端不同。如果TCP客戶端不明確繫結埠的話,核心會自動為socket繫結一個可用的埠。當然,TCP客戶端也可以主動繫結一個埠。繫結埠以後,開始監聽這個埠,等待有客戶端發起連線。當與客戶端建立好連線後,會得到與客戶端連線的套接字描述符,就可以和客戶端通訊了。通訊結束後關閉套接字。

下面簡單介紹一下新用到的函式,其他函式可以參考《Linux網路程式設計(1)》這篇文章。

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
int listen(int sockfd, int backlog);
int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

bind()函式用來給一個socket描述符繫結一個指定的埠。成功返回0,失敗返回-1。第一個引數是socket描述符,後兩個引數分別是本地的地址和地址的大小。其中第二個引數裡面的sin_port就是要繫結的埠號。一般來說sin_addr.s_addr都是使用INADDR_ANY,表示任意IP。如果指定了一個IP地址,那麼只有來自這個IP的連線可以被接受。

listen()函式只能由伺服器端使用,它用來監聽某一埠。成功返回0,失敗返回-1。第一個引數是socket描述符,第二個引數backlog是核心應該為相應套接字排隊的最大連線個數。這個引數一般設定為5,但是在繁忙的伺服器應用裡,可以設定的大一些。但是如果這個值比核心支援的最大值還要大時,核心會把它修改為自身支援的最大值。

accept()函式用來等待客戶端的連線。成功時返回一個新的與客戶端連線的套接字描述符,失敗時返回-1。accept()函式預設是阻塞的。第一個引數是用來監聽的socket描述符,第二個引數是一個返回值,表示客戶端的地址。第三個引數所指的整數的值在呼叫accept()函式之前,應該是用來接收客戶端地址的地址大小,也就是第二個引數所指的結構體的大小。accept()函式返回後,第三個引數所指的整數的值表示客戶端地址的實際大小。

下面將實現一個簡單的TCP回射伺服器,即從客戶端收到什麼資料,就傳送什麼資料。

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

#define BUFFER_SIZE 1024

int main(int argc, char** argv)
{
    if(argc != 2)
    {
        printf("Usage:\n%s <port>", argv[0]);
        return 0;
    }

    struct sockaddr_in myAddr, clientAddr;
    int socketFd, clientFd;
    unsigned int clientAddrLen = sizeof(clientAddr);
    int receivedLength;
    char buffer[BUFFER_SIZE];

    memset(&clientAddr, 0, sizeof(clientAddr));
    memset(&myAddr, 0, sizeof(myAddr));
    myAddr.sin_family = AF_INET;
    myAddr.sin_port = htons(atoi(argv[1]));
    myAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    socketFd = socket(AF_INET, SOCK_STREAM, 0);
    bind(socketFd, (struct sockaddr*)&myAddr, sizeof(myAddr));
    listen(socketFd, 5);
    clientFd = accept(socketFd, (struct sockaddr *)&clientAddr, &clientAddrLen);
    receivedLength = recv(clientFd, buffer, BUFFER_SIZE, 0);
    buffer[receivedLength] = '\0';
    printf("Received a message from %s:%u:\n%s\n"
        , inet_ntoa(clientAddr.sin_addr)
        , ntohs(clientAddr.sin_port),buffer);
    send(clientFd, buffer, receivedLength, 0);
    close(clientFd);
    close(socketFd);

    return 0;
}

假設這個程式的名字是TcpServer,在編譯好的可執行檔案的目錄下,輸入:./TcpServer 2333啟動伺服器程式

然後使用netcat來向它發起來接:nc 127.0.0.1 2333

在netcat裡輸入一些字元,按回車以後,可以在TcpServer的輸出中看到收到的資料,在netcat裡可以看到伺服器返回的資料。

也可以和《Linux網路程式設計(1)》裡面的程式相互測試一下效果。



相關推薦

Linux網路程式設計2簡單TCP伺服器Echo Server

先介紹一下TCP伺服器大概的工作流程。首先,和TCP客戶端一樣,需要建立一個套接字,然後必須給套接字繫結一個埠。這一點和TCP客戶端不同。如果TCP客戶端不明確繫結埠的話,核心會自動為socket繫結一個可用的埠。當然,TCP客戶端也可以主動繫結一個埠。繫結埠以後,開始監聽

Linux網路程式設計【三】:TCP伺服器多程序和多執行緒http訪問版本

為了讓伺服器同時接受多個客戶端訪問,所以需要多程序或者多執行緒 多程序版本: #include<unistd.h> #include<stdio.h> #include<stdlib.h> #include<sys/types.h

linux網路程式設計之用select函式實現io複用基於TCP引發的思考

1、基本概念    IO多路複用是指核心一旦發現程序指定的一個或者多個IO條件準備讀取,它就通知該程序。IO多路複用適用如下場合:   (1)當客戶處理多個描述字時(一般是互動式輸入和網路套介面),必須使用I/O複用。   (2)當一個客戶同時處理多個套介面時,而這種情況

linux網路程式設計之用select方法實現io複用基於udp

1、基本概念   IO多路複用是指核心一旦發現程序指定的一個或者多個IO條件準備讀取,它就通知該程序。IO多路複用適用如下場合:   (1)當客戶處理多個描述字時(一般是互動式輸入和網路套介面),必須使用I/O複用。   (2)當一個客戶同時處理多個套介面時,而這種情況是

資料報套接字——簡單伺服器示例

文章目錄 Server Client Server #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h>

流式套接字——簡單伺服器示例

文章目錄 Server Client Server #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h>

linux網路程式設計之用socket實現簡單客戶端和服務端的通訊基於TCP

一、介紹基於TCP協議通過socket實現網路程式設計常用API 1、讀者如果不是很熟悉,可以先看我之前寫的幾篇部落格,有socket,地址結構的理解,更加方便讀者理解 地址分別是: 2、socket(TCP)程式設計API簡介 1)、socket int s

Linux 網路程式設計 全解--------TCP三次握手、資料傳輸、四次揮手、滑動視窗

寫在前面:今天中秋佳節,首先祝大家佳節快樂,身體健康,恭喜發財。吃也吃了,喝也喝了,玩也玩了,乾點正事吧。 說一下寫這個系列的目的,隨著對物聯網開發的深入,越來越覺得自己網路基礎知識的薄弱,雖然開發過程中不需要對網路基礎有很深入的瞭解照樣能進行,但有一些問題仍然是不知其因,

嵌入式linux網路程式設計TCP、IP協議原理,wireshark抓包工具,乙太網頭Ethernet header,IP頭,TCP頭,三次握手,四次握手,UDP頭

文章目錄 1,wireshark抓包工具 1.1,wireshark安裝 1.2,wireshark啟動 1.2.1,出現錯誤警告 1.2.2,解決方案 2,常用除錯測試工具 3,TCP

Linux 網路程式設計 全解--------TCP狀態切換

寫在前面: 正文: 一、TCP狀態切換 先貼一張TCP的狀態轉換圖,如下:   圖中:實線部分為主動發起的,虛線部分為被動相應的。 1、先來看主動發起連線請求(一般是client)的狀態變化:                            

TCP —— Linux網路程式設計 API基礎準備

基礎知識:   首先我們來了解Linux網路API:   ①socket地址API: socket最開始的含義:一個IP地址和埠對(ip,port)。他唯一的表示了TCP通訊的一端。   ②socket基礎API: socket主要的API包括建立sock

Linux網路程式設計:一個簡單的socket程式

伺服器: /* *tcp_server.c */ #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include

linux網路程式設計之用socket實現簡單客戶端和服務端的通訊基於UDP

1、sendto和recvfrom函式介紹 sendto(經socket傳送資料) 相關函式 send , sendmsg,recv , recvfrom , socket 表頭檔案 #include < sys/types.h >#includ

linux網路程式設計練習---聊天室TCP/IP實現

為了更深刻的鍛鍊認識TCP/IP協議,加強自己對Linux系統的網路程式設計部分的編寫程式碼能力,編寫基於控制檯的聊天視窗,用本機既當伺服器又當客戶端,先開啟一個shell,執行伺服器程式,然後再開啟一個shell視窗,執行客戶端程式,顯示連線成功,開始聊天吧。不知道為什麼

Linux網路程式設計——tcp併發伺服器poll實現

#include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/select.h> #include <sys/time.

Linux網路程式設計】基於TCP多程序fork版本客戶端/伺服器

客戶端程式碼: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h

java網路程式設計:8、基於TCP的socket程式設計簡單的socket通訊_一個客戶端

宣告:本教程不收取任何費用,歡迎轉載,尊重作者勞動成果,不得用於商業用途,侵權必究!!! 文章目錄 一、基於tcp的程式設計,就好像用電話進行交談一樣 二、在java中用於程式設計網路程式的類 三、套接字 + (輸出、輸入流) 1、伺服器程式編寫基本步驟: 2、客戶端程式

Linux----網路程式設計TCP網路通訊客戶端伺服器程式設計實現多程序

1、伺服器ser.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <assert.h> 5 #in

Linux----網路程式設計TCP網路通訊伺服器客戶端程式設計流程與其迴圈實現

一、TCP的伺服器客戶端程式設計流程 1、伺服器 ser.c 1 #include <stdio.h> 2 #include <assert.h> 3 #incl

linux網路程式設計TCP/IP基礎:利用ARP和ICMP協議解釋ping命令

一、MTU 乙太網和IEEE 802.3對資料幀的長度都有限制,其最大值分別是1500和1492位元組,將這個限制稱作最大傳輸單元(MTU,Maximum Transmission Unit)。如果I