linux IPC socket

来源:http://www.cnblogs.com/ch122633/archive/2017/12/21/8074110.html
-Advertisement-
Play Games

套接字是通訊端點的抽象 創建一個套接字 套接字通信是雙向的。可以禁止一個套接字的I/O 用來在處理器位元組序和網路位元組序之間實施轉換的函數 h表示主機位元組序,n表示網路位元組序,l表示長整型,s表示短整型 列印出能被人理解而不是電腦所理解的地址格式。同時支持IPv4和IPv6地址 找到給定電腦系統的 ...


套接字是通訊端點的抽象

 

創建一個套接字

#include <sys/types.h>
#include <sys/socket.h>

int socket(int domain, int type, int protocol);
返回值:成功文件(套接字)描述符,失敗-1
domain:即協議域,又稱為協議族(family)。常用的協議族有,AF_INET、AF_INET6、AF_LOCAL(或稱AF_UNIX,Unix域socket)、AF_ROUTE等等。 協議族決定了socket的地址類型,在通信中必須採用對應的地址,如AF_INET決定了要用ipv4地址(32位的)與埠號(16位的)的組合、AF_UNIX決定了要用一個絕對路徑名作為地址。 type:指定socket類型。常用的socket類型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等(socket的類型有哪些?)。 protocal:故名思意,就是指定協議。常用的協議有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等 它們分別對應TCP傳輸協議、UDP傳輸協議、STCP傳輸協議、TIPC傳輸協議。

 

套接字通信是雙向的。可以禁止一個套接字的I/O

#include <sys/socket.h>

int shutdown(int sockfd, int how);
返回值:成功0,出錯-1
sockfd:套接字的描述符
how:三種SHUT_RD(0)關閉sockfd上的讀功能
SHUT_WR(1)關閉sockfd上的寫功能
SHUT_RDWR(2)關閉sockfd的讀寫功能

 

用來在處理器位元組序和網路位元組序之間實施轉換的函數

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
返回值:以網路位元組序表示的32位整數 uint16_t htons(uint16_t hostshort);
返回值:以網路位元組序表示的16位整數
uint32_t ntohl(uint32_t netlong);
返回值:以主機位元組序表示的32位整數
uint16_t ntohs(uint16_t netshort);
返回值:以主機位元組序表示的16位整數

 h表示主機位元組序,n表示網路位元組序,l表示長整型,s表示短整型

 

列印出能被人理解而不是電腦所理解的地址格式。同時支持IPv4和IPv6地址

#include <arpa/inet.h>

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
返回值:成功地址字元串指針,出錯NULL
af:地址簇,僅支持AF_INET和AF_INET6
src:來源地址結構指針
dst:接收轉換後的字元串
size:保存文本字元串的緩衝區大小

int inet_pton(int af, const char *src, void *dst);
返回值:成功1,格式無效0,出錯-1
af:地址簇,僅支持AF_INET和AF_INET6
src:轉換的地址字元串
dst:轉換後的地址結構指針

這個很常用,所有使用socket都需要用這兩個函數轉換,p應該是protocol,n應該是net吧。

例子

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <sys/types.h>
 4 #include <sys/ioctl.h>
 5 #include <stdlib.h>
 6 #include <netdb.h>
 7 #include <arpa/inet.h>
 8 #include <netinet/in.h>
 9 #include <string.h>
10 
11 int main(int argc, char *argv[])
12 {
13         char dst[100];
14         int sockfd = socket(AF_INET, SOCK_STREAM, 0);
15 
16         struct sockaddr_in serv;
17         memset(&serv, 0 ,sizeof(struct sockaddr_in));
18 
19         serv.sin_family = AF_INET;
20         serv.sin_port = htons(5555);
21 
22         if((inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr)) == 0)
23                 printf("inet_pton error\n");
24         if((inet_ntop(AF_INET, &serv.sin_addr.s_addr, dst, sizeof(dst))) == NULL)
25                         printf("inet_ntop error\n");
26         printf("dst=%s,sizeof(dst)=%d\n", dst, sizeof(dst));
27 
28         bind(sockfd, (struct sockaddr *)&serv, sizeof(serv));
29         listen(sockfd, 15);
30         return 0;
31 }
inet_pton

  

找到給定電腦系統的主機信息

#include <netdb.h>

struct hostent *gethostent(void);
返回值:成功返回指針,出錯NULL

void sethostent(int stayopen);
stayopen:true就是TCP,否則UDP
void endhostent(void);

 

能夠採用一套相似的介面來獲得網路名字和網路編號

#include <netdb.h>

struct netent *getnetbyaddr(uint32_t net, int type);
struct netent *getnetbyname(const char *name);
struct netent *getnetent(void);
返回值:成功返回指針,出錯NULL

void setnetent(int stayopen);
void endnetent(void);

 

在協議名字和協議編號之間進行映射

#include <netdb.h>

struct protoent *getprottobyname(const char *name);
struct protoent *getprotobynumber(int proto);
struct protoent *getprotoent(void);
返回值:成功返回指針,出錯NULL

void setprotoent(int stayopen);
void endprotoent(void);

 

服務是由地址的埠號部分表示的,每個服務由一個唯一的眾所周知的埠號來支持。可以使用getservbyname將一個服務名映射到一個埠號,使用函數getservbyport將一個埠號映射到一個服務名,使用函數getservent順序掃描服務資料庫。

#include <netdb.h>

struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);
struct servent *getservent(void);
返回值:成功返回指針,出錯NULL

void setservent(int stayopen);
void endservent(void);

 

將一個主機和一個服務名映射到一個地址

#include <sys/socket.h>
#include <netdb.h>

int getaddrinfo(const char *node, const char *service,
                        const struct addrinfo *hints,
                        struct addrinfo **res);
返回值:成功0,出錯非0錯誤碼
node:向一個主機名(功能變數名稱)或者地址串(IPv4的點分十進位串或者IPv6的16進位串)。
service:指向一個服務名或者10進位埠號數串。
hints:可以是一個空指針,也可以是一個指向某個addrinfo結構的指針
res:指向的變數已被填入一個指針,它指向的是由其中的ai_next成員串聯起來的addrinfo結構鏈表
void freeaddrinfo(struct addrinfo *res);

addrinfo結構體

struct addrinfo
{ 
    int ai_flags; 
    int ai_family; //AF_INET,AF_INET6,UNIX etc
    int ai_socktype; //STREAM,DATAGRAM,RAW
    int ai_protocol; //IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc
    size_t ai_addrlen;//length of ai_addr
    char* ai_canonname; //full hostname 
    struct sockaddr* ai_addr; //addr of host
    struct addrinfo* ai_next;
}

 

錯誤碼需要調用函數來轉換成錯誤消息

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

const char *gai_strerror(int errcode);

 

將一個地址轉換成一個額主機名和一個服務名

#include <sys/socke.h>
#include <netdb.h>

int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                        char *host, socklen_t hostlen,
                        char *serv, socklen_t servlen, int flags);
返回值:成功0,出錯非0值
sa:指向包含協議地址的套介面地址結構,它將會被轉換成可讀的字元串,
salen:結構的長度,這個結構長度通常由accept、recvfrom、getsockname、getpeername
host:主機字元串
hostlen:長度
serv:伺服器字元串
servlen:長度
flags:標誌位可以有多個用與或

 sockaddr結構體

struct sockaddr {   unsigned short sa_family;  /*addressfamily,AF_xxx*/   char sa_data[14];       /*14bytesofprotocoladdress*/ };

 

16-9.c

  1 #include "apue.h"
  2 #if defined(SOLARIS)
  3 #include <netinet/in.h>
  4 #endif
  5 #include <netdb.h>
  6 #include <arpa/inet.h>
  7 #if defined(BSD)
  8 #include <sys/socket.h>
  9 #include <netinet/in.h>
 10 #endif
 11 
 12 void print_family(struct addrinfo *aip)
 13 {
 14     printf(" family ");
 15     switch(aip->ai_family) {
 16     case AF_INET:
 17         printf("inet");
 18         break;
 19     case AF_INET6:
 20         printf("inet6");
 21         break;
 22     case AF_UNIX:
 23         printf("unix");
 24         break;
 25     case AF_UNSPEC:
 26         printf("unspecified");
 27         break;
 28     default:
 29         printf("unknown");
 30     }
 31 }
 32 
 33 void print_type(struct addrinfo *aip)
 34 {
 35     printf(" type ");
 36     switch(aip->ai_socktype) {
 37     case SOCK_STREAM:
 38         printf("stream");
 39         break;
 40     case SOCK_DGRAM:
 41         printf("datagram");
 42         break;
 43     case SOCK_SEQPACKET:
 44         printf("seqpacket");
 45         break;
 46     case SOCK_RAW:
 47         printf("raw");
 48         break;
 49     default:
 50         printf("unknown (%d)", aip->ai_socktype);
 51     }
 52 }
 53 
 54 void print_protocol(struct addrinfo *aip)
 55 {
 56     printf(" protocol ");
 57     switch(aip->ai_protocol) {
 58     case 0:
 59         printf("default");
 60         break;
 61     case IPPROTO_TCP:
 62         printf("TCP");
 63         break;
 64     case IPPROTO_UDP:
 65         printf("UDP");
 66         break;
 67     case IPPROTO_RAW:
 68         printf("raw");
 69         break;
 70     default:
 71         printf("unknown (%d)", aip->ai_protocol);
 72     }
 73 }
 74 
 75 void print_flags(struct addrinfo *aip)
 76 {
 77     printf("flags");
 78     if(aip->ai_flags == 0) {
 79         printf(" 0");
 80     } else {
 81         if(aip->ai_flags & AI_PASSIVE)
 82             printf(" passive");
 83         if(aip->ai_flags & AI_CANONNAME)
 84             printf(" canon");
 85         if(aip->ai_flags & AI_NUMERICHOST)
 86             printf(" numhost");
 87         if(aip->ai_flags & AI_NUMERICSERV)
 88             printf(" numserv");
 89         if(aip->ai_flags & AI_V4MAPPED)
 90             printf(" v4mapped");
 91         if(aip->ai_flags & AI_ALL)
 92             printf(" all");
 93     }
 94 }
 95 
 96 int main(int argc, char *argv[])
 97 {
 98     struct addrinfo *ailist, *aip;
 99     struct addrinfo hint;
100     struct sockaddr_in *sinp;
101     const char *addr;
102     int err;
103     char abuf[INET_ADDRSTRLEN];
104 
105     if(argc != 3)
106         err_quit("usage: %s nodename service", argv[0]);
107     hint.ai_flags = AI_CANONNAME;
108     hint.ai_family = 0;
109     hint.ai_socktype = 0;
110     hint.ai_protocol = 0;
111     hint.ai_addrlen = 0;
112     hint.ai_canonname = NULL;
113     hint.ai_addr = NULL;
114     hint.ai_next = NULL;
115     if((err = getaddrinfo(argv[1], argv[2], &hint, &ailist)) != 0)
116         err_quit("getaddrinfo error %s", gai_strerror(err));
117     for(aip = ailist; aip != NULL; aip = aip->ai_next) {
118         print_flags(aip);
119         print_family(aip);
120         print_type(aip);
121         print_protocol(aip);
122         printf("\n\thost %s", aip->ai_canonname?aip->ai_canonname:"-");
123         if(aip->ai_family == AF_INET) {
124             sinp = (struct sockaddr_in *)aip->ai_addr;
125             addr = inet_ntop(AF_INET, &sinp->sin_addr, abuf, INET_ADDRSTRLEN);
126             printf(" address %s", addr?addr:"unknown");
127             printf(" port %d", ntohs(sinp->sin_port));
128         }
129         printf("\n");
130     }
131     exit(0);
132 }
getaddrinfo

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • HashTable和Dictionary的區別 1.HashTable 哈希表(HashTable)表示鍵/值對的集合。在.NET Framework中,Hashtable是System.Collections命名空間提供的一個容器,用於處理和表現類似key-value的鍵值對,其中key通常可用來 ...
  • 1.先上效果 將所有節點加入ComboBox數據源,在ComboBox中選擇時下方Treeview顯示該節點下的子節點。 1.xaml文件,將以下代碼加入界面合適位置 2.後臺代碼 a.用於綁定的節點類 b.主界面類代碼 ...
  • 如果想支持 .xls,.xlsx 兩種格式 則必須安裝一個exe文件,下載路徑https://www.microsoft.com/zh-CN/download/details.aspx?id=13255 下載好安裝就支持.xls,.xlsx 兩種格式轉換成datatable了, 附代碼 public ...
  • 報錯信息:Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities we ...
  • 報錯信息:LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression 參考 ...
  • C# 開發環境: VisualStudio2015 資料庫: SQLserver2008 程式主界面: 註釋: lbl標簽: 程式中的lbl標簽:編號、人數、姓名、性別、請輸入要查詢的信息,這裡他們只起到了說明作用,所有命名一般為預設,只修改Text文本。 程式中的lbl標簽:編號後面的0,他起到了 ...
  • 一.什麼是I/0流? 英文翻譯:Input/Output,在程式里簡單的理解為讀寫數據操作數據的意思。流操作是為瞭解決體積大數據占用太多的記憶體,就是分段進行操作。就跟我們吃飯一樣,一口一口的吃,還沒見過誰直接一口吃完的。流就是細水長流。 在我們強大的Net中,就是微軟為了簡化我們的工作,為了我們能對 ...
  • 現有兩段基本一樣的代碼,只是變數進行改變,其他都沒有變化,但是執行過程中出現了不一樣的結果 代碼一: 代碼二: 上面代碼只是修改了打包的情況,tar zcf /backup和定義一個變數tar $Path/結果就出現不一樣的情況,第一種執行結果是: 代碼一執行結果: [root@nfs01 back ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...