1. 程式人生 > >Socket網路程式設計(1) ———— 基於TCP協議的客戶-伺服器socket例項

Socket網路程式設計(1) ———— 基於TCP協議的客戶-伺服器socket例項

Socket網路程式設計(1)

———— 基於TCP協議的客戶-伺服器socket例項

1、TCP網路程式設計架構

這裡寫圖片描述

2、程式碼段

  • 伺服器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 8888                       /*偵聽埠地址*/
#define BACKLOG 2 /*偵聽佇列長度*/ int main(int argc, char *argv[]) { int ss,sc; /*ss為伺服器的socket描述符,sc為客戶端的socket描述符*/ struct sockaddr_in server_addr; /*伺服器地址結構*/ struct sockaddr_in client_addr; /*客戶端地址結構*/ int err; /*返回值*/ pid_t pid; char
words[1024]; /*分叉的進行ID*/ /*建立一個流式套接字*/ ss = socket(AF_INET, SOCK_STREAM, 0); if(ss < 0){ /*出錯*/ printf("socket error\n"); return -1; } /*設定伺服器地址*/ bzero(&server_addr, sizeof(server_addr)); /*清零*/ server_addr.sin_family = AF_INET; /*協議族*/
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*本地地址*/ server_addr.sin_port = htons(PORT); /*伺服器埠*/ /*繫結地址結構到套接字描述符*/ err = bind(ss, (struct sockaddr*)&server_addr, sizeof(server_addr)); if(err < 0){/*出錯*/ printf("bind error\n"); return -1; } /*設定偵聽*/ err = listen(ss, BACKLOG); if(err < 0){ /*出錯*/ printf("listen error\n"); return -1; } /*主迴圈過程*/ for(;;) { socklen_t addrlen = sizeof(struct sockaddr); sc = accept(ss, (struct sockaddr*)&client_addr, &addrlen); /*接收客戶端連線*/ if(sc < 0){ /*出錯*/ continue; /*結束本次迴圈*/ }else{ sprintf(words, "%d login\n", sc); write(1, words, strlen(words)+1); } /*建立一個新的程序處理到來的連線*/ pid = fork(); /*分叉程序*/ if( pid == 0 ){ /*子程序中*/ //process_conn_server(sc); /*處理連線*/ ssize_t size = 0; char buffer[1024]; /*資料的緩衝區*/ for(;;){ /*迴圈處理過程*/ size = read(sc, buffer, 1024); /*從套接字中讀取資料放到 緩衝區buffer中*/ if(size == 0){ /*沒有資料*/ return; } write(1, buffer, size); /*寫到標準輸出*/ sprintf(buffer, "From %d\n", sc); write(1, buffer, strlen(buffer)+1); /*寫到標準輸出*/ /*構建響應字元,為接收到客戶端位元組的數量*/ sprintf(buffer, "I receive %d bytes altogether\n", size); write(sc, buffer, strlen(buffer)+1);/*發給客戶端*/ } close(ss); /*在子程序中關閉伺服器的偵聽*/ }else{ //close(sc); /*在父程序中關閉客戶端的連線*/ } } }
  • 客戶端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8888                               /*偵聽埠地址*/
#define IP "127.0.0.1"                              /*伺服器IP地址*/

int main(int argc, char *argv[])
{
    int s;                                      /*s為socket描述符*/
    struct sockaddr_in server_addr;         /*伺服器地址結構*/

    s = socket(AF_INET, SOCK_STREAM, 0);        /*建立一個流式套接字 */
    if(s < 0){                                  /*出錯*/
        printf("socket error\n");
        return -1;
    }

    /*設定伺服器地址*/
    bzero(&server_addr, sizeof(server_addr));   /*清零*/
    server_addr.sin_family = AF_INET;                   /*協議族*/
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);    /*本地地址*/
    server_addr.sin_port = htons(PORT);             /*伺服器埠*/

    /*將使用者輸入的字串型別的IP地址轉為整型*/
    inet_pton(AF_INET, IP, &server_addr.sin_addr);
    /*連線伺服器*/
    connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));
    //process_conn_client(s);                       /*客戶端處理過程*/


    ssize_t size = 0;
    char buffer[1024];                          /*資料的緩衝區*/

    for(;;){                                    /*迴圈處理過程*/
        /*從標準輸入中讀取資料放到緩衝區buffer中*/
        size = read(0, buffer, 1024);
        if(size > 0){                           /*讀到資料*/
            write(s, buffer, size);             /*傳送給伺服器*/
            size = read(s, buffer, 1024);       /*從伺服器讀取資料*/
            write(1, buffer, size);             /*寫到標準輸出*/
        }
    }


    close(s);                                   /*關閉連線*/
    return 0;
}
  • makefile:
all:client server clean                 #all規則,它依賴於client和server規則

client: tcp_client.o    #client規則,生成客戶端可執行程式
    gcc -o client tcp_client.o
server: tcp_server.o    #server規則,生成伺服器端可執行程式
    gcc -o server tcp_server.o  
clean:                              #清理規則,刪除client、server和中間檔案
    rm -f tcp_process tcp_client tcp_server *.o

3、效果展示

  • 伺服器
    這裡寫圖片描述
    不同客戶端連線,會顯示不同id登入,當傳送資訊時,也會顯示是來自哪個客戶端。

  • 客戶端
    這裡寫圖片描述
    兩個客戶端的連線,當傳送資訊時,會受到伺服器的返回,顯示收到的字元數