1. 程式人生 > >Linux下簡單的網路程式設計筆記(模擬簡單的伺服器與客戶端的通訊 1-伺服器端)

Linux下簡單的網路程式設計筆記(模擬簡單的伺服器與客戶端的通訊 1-伺服器端)

一.伺服器端    

(一).建立連線的條件:伺服器必須處於監聽狀態,由客戶端發起連線請求

    bind之前可新增以下程式碼解決關閉伺服器後端口仍被佔用的問題

  • // 設定套接字選項避免地址使用錯誤  
  •     int on=1;  
  •     if((setsockopt(server_sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)))<0)  
  •     {  
  •         perror("setsockopt failed");  
  •         exit(EXIT_FAILURE);  
  •     }  

1.建立連線

(1)伺服器端:*1.建立套接字:socket (IP型別 ,   協議型別,     其他協議);

              IP型別涉及兩種,IPV4:設定為AF_INET     IPV6:設定為AF_INET6    

              協議型別兩種,TCP:設定為  SOCK_STREAM    UDP:設定為 SOCK_DGRAM 

              其他協議本節中不涉及,預設為置0;     返回值為一個標誌符,暫且設為sockfd

              *2.繫結sockfd、IP和埠:bind(sockfd包含傳入IP,埠號協議型別的機構體

  ,結構體的長度)

                該結構體為:struct sockaddr_in addr={0}

                進行初始化:addr.sin_family=AF_INET;  addr.sin_port=htons(給伺服器定義的埠號);

                            addr.sin_addr.s_addr=inet_addr("192.168.1.102");

           埠號轉換的函式四種(上面的htons函式)

1.uint32_t | htonl(埠號);主機埠號轉換為32位2進位制網路傳輸形式   host to net long

           2.uint16_t | htons();      host to net short

           3. .....   | ntohl();      

           4. .....   | ntohs();

          *3.伺服器端進行監聽:listen(sockfdBacklog);      監聽物件是埠

           監聽指定埠,通知系統去接收來自客戶端對這個埠的連線請求,將連線請求放入到對應的佇列中,而這個

           Backlog就是指定這個佇列的長度,直接就是一個int型別數字;

         *4.伺服器阻塞等待客戶端的連線:accept(sockfd , 儲存返回客戶機IP、埠的的一個結構體結構體的長度 );

            這個結構體和*2中的結構體型別相同,自己定義,初始化為0,struct sockaddr_in client={0};注意:(它存放

的是客戶端的資訊)     若沒有客戶端連線上來就會一直阻塞

將其傳入到accept函式中,客戶端連線後會被賦值    (注意強制轉換(struct sockaddr *)&)

          返回值返回值是根據不同客戶端的連線而產生的一個對應檔案描述符fd,得到這個對應的fd後就可以通過send

          和recv讀寫,從而實現網路傳輸。

  TCP/UDP段結構中,埠地址都是16位,在0~65535之間,1024以內的埠號不能自己拿來用,

#include <sys/types.h> 
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SVERPNET "192.168.0.110"                   //伺服器ip地址;
#define Myport 6003                                //伺服器的埠號;
#define Backlog 100
#define SHUTDOWN "斷開"

int main(int argc,char *argv[])
{
   
    //1.建立套接字
    //2.繫結埠和ip地址
    int sockfd=-1;             //套接字返回值
    int bindfd=-1;             //繫結函式返回值
    int listenfd=-1;           //監聽函式返回值
    char savedate[100]={0};    //儲存接收資訊空間
    int recvfd=-1;             //讀函式返回值
    int acceptfd=-1;           //
    int a=-1;
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(-1==sockfd)
    {
	perror("socket");       //返回值驗證
	return -1;
    }
    printf("sockfd=%d\n",sockfd);
    /*上面部分為建立套接字*/

    //定義結構體並初始化
    struct sockaddr_in svraddr={0};    //bind函式需要傳入的ip埠結構體

    svraddr.sin_family=AF_INET;        //1 //ip型別 ipv4;

    svraddr.sin_port=htons(Myport);    //2 //埠號 需要轉換成機器能識別的埠號不能直接等於6300

    svraddr.sin_addr.s_addr=inet_addr(SVERPNET);  //3 //ip
    //繫結埠和ip
    bindfd=bind(sockfd,(const struct sockaddr *)&svraddr,sizeof(svraddr));
    if(-1==bindfd)
    {
        perror("bind");
        return -1;
    }
    printf("bind success.\n");
    printf("bindfd=%d\n",bindfd);
    //3.第三步:listen 監聽埠
    listenfd=listen(sockfd,Backlog);
    if(-1==listenfd)
    {
        perror("listen");
        return -1;
    }
    //4.第四步:accept伺服器阻塞等待連線
    struct sockaddr_in Acceptretaddr={0};
    socklen_t lenth={0};
    printf("等待客戶端連線\n");
    acceptfd=accept(sockfd,(struct sockaddr *)&Acceptretaddr,&lenth);
    if(-1==acceptfd)
    {
        perror("accept");
        return -1;
    }
    printf("客戶端成功連線!\n");
    //第五步:伺服器接收資料
    while(1)
    {
    recvfd=recv(acceptfd,savedate,sizeof(savedate),0);
    if(-1==recvfd)
    {
        perror("recv");
        return -1;
    }else{
        a=strcmp(savedate,SHUTDOWN);
        if(0==a)
        {
            return 0;
            exit(0);
        }
        printf("接收到資料%d個字元\n",recvfd);
        printf("%s\n",savedate);
         }
        
    memset(savedate,0,sizeof(savedate));
    }
    return 0;
}

   
    ret=inet_pton(AF_INET,SVERPNET,&addr);      //輔助性函式1 :將點分式IP地址轉換為32位2進位制進行網路傳輸 
   if(ret!=1)
    {
        printf("inet_pton error\n");
        return -1;
    }
    else{
        printf("addr=0x%x\n",addr.s_addr);
        return 0;
    }*/
   // struct in_addr addr={0};
    //char buf[50]={0};
    //addr.s_addr=0x6601a8c0;
    //inet_ntop(AF_INET,&addr,buf,sizeof(buf));
    //printf("%s\n",buf);}

相關推薦

Linux簡單網路程式設計筆記模擬簡單伺服器客戶通訊 1-伺服器

一.伺服器端     (一).建立連線的條件:伺服器必須處於監聽狀態,由客戶端發起連線請求     bind之前可新增以下程式碼解決關閉伺服器後端口仍被佔用的問題 // 設定套接字選項避免地址使用錯誤       int on=1;       if((setsoc

網路程式設計 筆記 基於 Windows簡單通訊

windows套接字程式設計 1、設定庫Alt+F7 ->“配置屬性”-> “聯結器” -> “輸入” -> “附加依賴項” -> “ws2_32.lib” 2、標頭檔案:#include <winsock2.h>

網路程式設計 筆記 I/O複用

select函式呼叫示例 #include <stdio.h> #include <unistd.h> #include <sys/time.h> #include <sys/select.h> #defi

Linux的socket程式設計實踐TCP服務優化和常見函式

併發下的殭屍程序處理 只有一個程序連線的時候,我們可以使用以下兩種方法處理殭屍程序: 1)通過忽略SIGCHLD訊號,避免殭屍程序     在server端程式碼中新增     signal(

網路程式設計 筆記多播廣播

多播 多播(Multicast)方式的資料傳輸時基於UDP完成的。 TTL(time of live),是決定“資料包傳遞距離”的主要因素。用整數表示,每經過一個路由器就減1,變為0時,資料包無法再傳遞,只能銷燬。 news_sender // /

網路程式設計 筆記 多程序伺服器

程序 - 程序(Process):“佔用記憶體空間的正在執行的程式” - 程序ID :作業系統給程序分配的id,其值大於2,1要分配給作業系統啟動後的首個程序 -linux檢視程序的命令:ps au ;引數a和u列出所有程序的詳細資訊 通過fo

Linux的socket程式設計實踐 Select的限制和poll併發的初步知識

select的限制 用select實現的併發伺服器,能達到的併發數一般受兩方面限制: 1)一個程序能開啟的最大檔案描述符限制。這可以通過調整核心引數來改變。可以通過ulimit -n(number)來調整或者使用setrlimit函式設定(需要root許可權),但一個系

網路程式設計 筆記 回聲伺服器/客戶

準備工作 1、執行平臺Mac 2、編輯器Xcode 3、語言C 建立工程 1、Xcode建立新的工程 - File->new->Project->os X->Command Line Tool, 後面就是設定工程名了

linuxC語言程式設計日誌1:基於TCP協議的伺服器/客戶程式

  基於TCP協議的伺服器/客戶端程式  首先我們看一下使用TCP協議進行網路通訊的程式基本模型:伺服器首先進行初始化操作:呼叫函式socket建立一個套接字,函式bind將這個套接字與伺服器的公認地址繫結在一起,函式listen將這個套接字換成傾聽套接字,然後呼叫函式acc

Linux的socket程式設計實踐Unix域協議和socketpair傳遞檔案描述符

UNIX域協議並不是一個實際的協議族,而是在單個主機上執行客戶/伺服器通訊的一種方法,所用API與在不同主機上執行客戶/伺服器通訊所使用的API相同。UNIX域協議可以視為IPC方法之一,Unix域協

LinuxSocket網路程式設計send和recv使用注意事項

1.send函式 ssize_t send( SOCKET s, const char *buf, size_t len, int flags ); (1)send先比較待發送資料的長度len和套接字s的傳送緩衝的長度, 如果len大於s的傳送緩衝區的長度,

Linux C 網路程式設計之 多執行緒通訊 例項

簡單示例,有不對的地方,歡迎指點。 伺服器端 /* ============================================================================ Name : sockThreadServer

Linux的socket程式設計實踐TCP的粘包問題和常用解決方案

TCP粘包問題的產生 由於TCP協議是基於位元組流並且無邊界的傳輸協議, 因此很有可能產生粘包問題。此外,傳送方引起的粘包是由TCP協議本身造成的,TCP為提高傳輸效率,傳送方往往要收集到足夠多的資料

LinuxOpencv入門程式設計影象取反

實現圖片畫素點的取反操作 -------------------------------------------------------------------------------------------------------------------- #includ

Linux的socket程式設計實踐設定套接字I/O超時的方案

(一)使用alarm 函式設定超時 #include <unistd.h>  unsigned int

HTTP圖解讀書筆記第五章 HTTP協作的web伺服器

一、單臺虛擬主機提供多個域名  HTTP/1.1 規範允許一臺 HTTP 伺服器搭建多個 Web 站點。這是因為利用了虛擬主機(Virtual Host,又稱虛擬伺服器)的功 能。 即使物理層面只有一臺伺服器,但只要使用虛擬主機的功能,則可以假想已具有多臺伺服器。 如果一臺伺服

Linux網路程式設計筆記day2程序

exec函式族: execlp --p – path 系統可執行程式 execl l --list 使用者自定義可執行程式 execv v --argv[] 命令列引數 execvp execve e environment 環境變數 只有失敗返回

Python 字串的連線、簡單替換unicode字串- 千月的python linux 系統管理指南學習筆記12

Python 下字串的連線、簡單替換與unicode字串 繼續上一章的內容,看一看字串的連線和替換 字串的連線 join() 將多個字串連線起來的”膠水“ 字元物件.join(字串或者列表) #連線字串,或者與列表裡的字元分別連線。 光是將2個字串相連。其實意義不大,一個

Linux學習之網路程式設計epoll的用法

言之者無罪,聞之者足以戒。 - “詩序” epoll相關的函式包含在標頭檔案<sys/epoll.h> epoll是Linux核心為處理大批量控制代碼而作了改進的poll,是Linux下多路複用IO介面select/poll的增強版本,它能顯著減少程式在大量併發連線中只有少量活躍

Linux學習之網路程式設計select

言之者無罪,聞之者足以戒。 - “詩序” 1、阻塞式I/O 下面看一下實現的邏輯: 2、非阻塞式I/O 下面看一下實現的邏輯: 3、I/O複用(select/epoll) (1)  int  select (int maxfdp, fd_set