Linux環境 C程式設計之網路通訊高階操作

2021-09-23 18:46:07 字數 3179 閱讀 7201

epoll 多路復用模型

套接字的阻塞和非阻塞模式

套接字選項

套接字選項詳細規定了套接字的屬性,影響socket的各項操作。我們可以通過setsockopt函 數和getsockopt函式愉快的設定和獲取socket的屬性。

首先來看一下setsockopt函式:

setsockopt函式

返回值:成功返回0,失敗返回-1

getsockopt函式

返回值:成功返回0,失敗返回-1

套接字api層常用的socket屬性

名稱選項

數值型別

so_broadcast

允許傳送廣播資料

intso_debug

允許除錯

intso_dontroute

不查詢路由

intso_error

獲得套接字錯誤

intso_keepalive

保持連線

intso_linger

延遲關閉連線

struct linger

so_oobinline

帶外資料放入正常資料流

intso_rcvbuf

接收緩衝區大小

intso_sndbuf

傳送緩衝區大小

intso_rcvlowat

接收緩衝區下限

intso_sndlowat

傳送緩衝區下限

intso_rcvtimeo

接收超時

struct timeval

so_sndtimeo

傳送超時

struct timeval

so_reuseaddr

允許重用本地位址和埠

intso_type

獲得套接字型別

intso_bsdcompat

與 bsd 系統相容

intepoll多路復用模型是linux中特有的,相比之前學過的select,參見linux環境:c程式設計檔案操作,epoll更加靈活,效能也更出色,支援水平觸發和邊緣觸發兩種觸發模式。

介面函式

epoll模型由三個函式組成:

int epoll_create(int size);//建立乙個epoll例項

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);//新增監控的套接字

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);//返回i/o就緒的套接字

函式原理:

//聯合體,事件觸發時返回的資訊,一般填對應的檔案描述符,來表示該事件由誰觸發

typedef union epoll_data epoll_data_t;

struct epoll_event

;

events可以是以下幾個巨集的集合:

epollin:表示對應的檔案描述符可以讀(包括對端socket正常關閉);

epollout:表示對應的檔案描述符可以寫;

epollpri:表示對應的檔案描述符有緊急的資料可讀(這裡應該表示有帶外資料到來);

epollerr:表示對應的檔案描述符發生錯誤;

epollhup:表示對應的檔案描述符被結束通話;

epollet: 將epoll設為邊緣觸發(edge triggered)模式,這是相對於水平觸發(level triggered)來說的。

epolloneshot:只監聽一次事件,當監聽完這次事件之後,如果還需要繼續監聽這個socket的話,需要再次把這個socket加入到epoll佇列裡

epoll_wait函式返回就緒的套接字列表,第乙個引數是epoll例項,第二個引數是返回的結構體陣列,每個元素對應乙個套接字的資訊,第三個列表是該結構體陣列的容量, 值不能大於epoll例項中就緒列表的最大長度,第四個引數是監視計時器(毫秒,0會立即返回,-1將不確定,也有說法說是永久阻塞)。該函式返回需要處理的事件數目,如返回0表示已超時。

觸發模式

lt模式:工作邏輯和select一致,只要緩衝區中存在沒有讀寫的資料就一直觸發。

et模式:僅當緩衝區狀態發生變化的時候才獲得通知。這裡的狀態的變化並不包括緩衝區中還有未處理的資料,也就是說,如果要採用et模式,需要一直read/write直到出錯為止,否則未讀寫的資料就會丟失。

套接字的預設狀態是阻塞狀態,即在進行bind,read,write,send,recv,connect,accept等操作時,如果沒有輸入,則會阻塞程序。

設定非阻塞套接字

可以通過設定檔案描述符的標誌位來把套接字設定為非阻塞模式。

用到以下函式:

int fcntl(int fd, int cmd);

int fcntl(int fd, int cmd, long arg);

int fcntl(int fd, int cmd, struct flock *lock);

fcntl函式可以獲取或者設定檔案的標誌位,fd是檔案描述符,cmd是命令,如果有第三個引數則是命令的引數。

通過以下**可以設定非阻塞套接字

//獲取當前檔案的檔案描述標誌位

int status=fcntl(fd,f_getfl);

//將該標誌位或上非阻塞標誌

status=status|o_nonblock;

//重新設定檔案的標誌位

fcntl(fd,f_setfl,status);

阻塞和非阻塞的區別

套接字呼叫可分為四種

非阻塞:

輸出操作,包括write,writev,send,sendto,sendmsg

阻塞: 非阻塞:

接收外來連線,即用於accept函式

發起外出連線,即用於tcp的connect函式。

Python 網路通訊程式設計之udp通訊程式設計

import socket 1.建立例項,即資料報套接字 server socket.socket socket.af inet,socket.sock dgram 2.繫結位址,進行監聽 server.bind 127.0.0.1 3120 3.收發訊息 while true data serve...

C 網路通訊程式設計

1 wcf wcf是rpc的一套框架和機制 系列文章 我的wcf之旅 1 系列文章列表 2 其中的入門 建立乙個簡單的wcf程式 2 http通訊 1 http協議簡介 這裡有比較詳細的入門級介紹 這個除了基本的類外,還有網路抓取的框架,是收費的。此外,他還有關於這些原理還程式設計的諸多介紹文章,都...

C 網路通訊

c 網路通訊 一 伺服器端程式 10.17 1.建立伺服器端socket 1 使用socket類 建立伺服器socket物件 socket objs new socket 引數 使用ipendpoint類設定伺服器ip位址和埠號 或使用dns類 ipaddress serip ipaddress.p...