網路程式設計高階 非網路通訊套接字

2021-05-02 09:29:39 字數 4203 閱讀 7744

1.非命名unix域套接字

linux下環境下使用socketpair函式創造一對未命名的,相互連線的unix域套接字:

#include

int socketpair(int domain,int type,int protocol,int sockfd);

第乙個引數用於表示建立的套接字的域,本地程序通訊時,用af_unix。

第二個引數表示要建立的套接字的型別,因為本地連線時可靠地,所以指定為sock_stream。

第三個引數表示所用的協議,通常設為0.

第四個引數表示儲存套接字描述符的陣列。

非命名unix域套接字類似於非命名管道,只有儲存了域套接字檔案描述符的程序可以使用它。

//s_pipe.c

#include

#include

#include

#include

#include

#define max 100

int main()

int sockfd[2];

pid_t pid;

char buf[max];

int n;

if(socketpair(af_unix,sock_stream,0,sockfd)==-1)else if(pid==0)

printf("the chlld done/n");

}else

/* 初始化函式,建立套接字,並且將該套接字繫結到乙個位址(指定的檔案)上

*  成功返回0,失敗返回-1

*  lfd : 指向儲存建立好的套接字的描述符的區域

*  path : 指定檔案的路徑,該檔案必須是不存在的,否則bind函式會出錯

*/int init(int *lfd, char *path)

/* 如果套接字檔案已經存在則刪除,否則unlink函式出錯,因此不檢查unlink函式的返回值 */

unlink(path);

/* 設定位址結構,該位址不再由ip位址和程序號組成,而是乙個檔案路徑 */

memset(&un_addr, 0, sizeof(un_addr));

un_addr.sun_family = af_unix; /* 使用unix域位址族 */

strcpy(un_addr.sun_path, path); /* 複製套接字檔案的路徑 */

len = offsetof(struct sockaddr_un, sun_path) + strlen(path); /* 計算檔案路徑的長度 */

/* 將套接字繫結到乙個位址結構上,該套接字可以開始通訊 */

if (bind(fd, (struct sockaddr *)&un_addr, len) == -1)

/* 開始監聽,最大連線數為10 */

if (listen(fd, 10) == -1)

*lfd = fd; /* 儲存套接字的檔案描述符 */

return 0; /* 執行到這裡,正常返回 */

err:

close(fd); /* 出錯,關閉套接字 */

return -1; /* 返回-1 */

}int main(void)

/* 得到客戶端檔案的路徑,並且設定結束符 */

len -= offsetof(struct sockaddr_un, sun_path);

un_addr.sun_path[len] = '/0';

/* 得到檔案愛你的狀態資訊,為了驗證客戶端程序的通訊時間

* 客戶端程序如果長期沒有修改通訊用的套接字檔案,說明該客戶端有可能已經結束通訊

* 下面分別驗證檔案的許可權和修改時間,這些操作並不是必須的

* 但是出於程式的完整性考慮,這些操作還是必要的

*/if (stat(un_addr.sun_path, &statbuf) == -1)

/* 檢查檔案的許可權,通訊用的套接字檔案的許可權必須是"rwx------"

* 也就是說之用所有者使用者可以有讀、寫和執行該檔案的許可權,其他使用者沒有

* 這說明unix域套接字只能用於同一使用者的程序之間的通訊

*/if ((statbuf.st_mode & (s_irwxg | s_irwxo)) || (statbuf.st_mode & s_irwxu) != s_irwxu)

/* 檢查套接字檔案的更新時間,超過三十秒鐘未作訪問和修改

* 說明客戶端程序可能已經斷開了連線,關閉連線套接字,結束連線

*/staletime = time(null) - stale;

if (statbuf.st_atime < staletime || statbuf.st_ctime < staletime || statbuf.st_mtime < staletime)

/* 刪除客戶端的套接字檔案

* 該套接字檔案由客戶端程序在呼叫bind函式進行套接字繫結的時候生成

*/if(unlink(un_addr.sun_path) == -1)

my_fun(buf); /* 呼叫大小寫轉換函式 */

if(write(cfd, buf, n) == -1)

close(cfd); /* 通訊結束,關閉套接字,準備下一次通訊 */

}/* 刪除伺服器程序的套接字檔案 */

if(unlink(path) == -1)

close(lfd);

return 0;

}4.uinx域套接字例項--客戶端

#include

#include

#include

#include

#include

#include

/* 使用/home/admin/connect.socket這個檔案作為通訊的套接字檔案 */

#define path "/home/admin/connect.socket"

/* 客戶端的套接字檔案路徑的目錄,檔名為程序的程序id */

#define c_path "/home/admin/"

#define max 1024

int main(void)

/* 設定客戶端程序使用的套接字的路徑名和套接字的域 */

memset(&un_addr, 0, sizeof(struct sockaddr_un));

un_addr.sun_family = af_unix;

/* 客戶端的套接字檔名為預設目錄 + 程序id */

sprintf(un_addr.sun_path, "%s%d", c_path, getpid());

len = offsetof(struct sockaddr_un, sun_path) + strlen(un_addr.sun_path);

/* 如果套接字檔案已經存在則刪除,否則unlink函式出錯,因此不檢查unlink函式的返回值 */

unlink(un_addr.sun_path);

/* 繫結客戶端套接字檔案,該檔案由伺服器端程序負責刪除 */

if (bind(cfd, (struct sockaddr *)&un_addr, len) == -1)

/* 改變套接字檔案的許可權為rwx------ */

if (chmod(un_addr.sun_path, s_irwxu) < 0)

memset(&un_addr, 0, sizeof(struct sockaddr_un));

un_addr.sun_family = af_unix;

strcpy(un_addr.sun_path, path); /* 伺服器套接字檔案的路徑 */

len = offsetof(struct sockaddr_un, sun_path) + strlen(buf);

/* 使用伺服器的套接字檔案進行連線 */

if(connect(cfd, (struct sockaddr *)&un_addr, len) < 0)

strcpy(buf, "china");

if(write(cfd, buf, strlen(buf) + 1) == -1)

/* 讀取伺服器程式發回的串*/

if(read(cfd, buf, max) == -1)

printf("recive from server: %s/n", buf); /* 列印該串 */

close(cfd);

return 0;

}

linux網路通訊套接字C S模型

server.c include include include include include include include error.h define serv port 8888 intmain void write accprt fd,buf,n close sfd close accp...

Linux 網路程式設計 高階套接字

一 套接字選項 有以下3中方式可以對套接字選項進行設定 getsockopt和setsockopt函式用於獲得和設定套接字的選項值,fcntl用來操作檔案描述符的有關屬性,比如設定套接字檔案描述符工作於非阻塞模式等,而ioctl用於控制i o裝置。套接字選項和協議層 協議層 level 選項 opt...

網路程式設計基礎 非阻塞套接字

1.非阻塞網路程式 伺服器端 由於套接字是一種特殊的檔案,因此,可以使用更改檔案阻塞狀態的方法修改套接字的阻塞狀態。當套接字被設定為非阻塞狀態時,如果對資料暫不可用的套接字進行讀寫操作,讀寫函式會返回 1,並置errno為eagain,表示當前資料不可用。下例同樣演示大小寫字母轉換的程式。serve...