最近項目有用到了socket本地通信,故復習一下。之前都是基于本地虛擬機的ip地址通信的,現在項目,Linux單板上面有2個進程需要通信,故用到了本地socket通信,主要其實就是用了sockfd,文件描述符,也叫句柄。
服務端代碼如下:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <unistd.h>/* 本地通信——基于socket文件進行數據傳遞 */#define SOCK_FILE "my.sock" // 定義存儲的socket文件名int main(int argc,char *argv[])
{printf("1. 服務器 創建socket套接字...\n");int sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0); // UDP協議if( sockfd == -1){perror("socket");return -1;}printf("2. socket套接字關聯到socket文件...\n");struct sockaddr_un addr; // 本地通信地址類型addr.sun_family = AF_LOCAL; // 地址簇strcpy(addr.sun_path, SOCK_FILE);// 綁定到物理內存,創建套接字文件int ret = bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));if (ret != 0 ) {perror("bind");return -1;}printf("3. 服務器循環接收數據...\n");while (1) {char buf[1024] = {};ssize_t rb = read(sockfd, buf, sizeof(buf));if (rb == -1) {perror("read");return -1;}// 當客戶端發送"!quit"關閉時,即結束循環if(rb == 0 || strcmp(buf,"!quit")==0)break;printf("receive: %s\n",buf);}printf("4. 服務器讀取數據完畢,關閉服務器...\n");close(sockfd);printf("5. 刪除套接字文件!\n");unlink(SOCK_FILE);return 0;
}
客戶端代碼如下:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <unistd.h>#define SOCK_FILE "my.sock" // 定義存儲的socket文件名int main(int argc,char *argv[])
{printf("1. 客戶端創建套接字...\n");int sockfd = -1;sockfd = socket(AF_LOCAL,SOCK_DGRAM,0);if (sockfd == -1) {perror("socket");return -1;}printf("2. 客戶端連接到服務器socket通信地址...\n");struct sockaddr_un addr;addr.sun_family = AF_LOCAL;strcpy(addr.sun_path, SOCK_FILE);// 請求連接,讓socket套接字連接到服務器的通信地址int ret = connect(sockfd,(const struct sockaddr*)&addr,sizeof(addr));if (ret != 0) {perror("connect");return -1;}printf("3. 客戶端循環發送數據...\n");while (1) {printf("請輸入:");char buf[1024] = {};fgets(buf, 1024, stdin);// 將獲取到的換行符替換成'\0'int len = strlen(buf);if (buf[len-1] == '\n') {--len;buf[len] = '\0';}int ret = 0;// 發送數據if ((ret = write(sockfd, buf, len + 1) ) < 0) {perror("write");return -1;}if (ret = 0 || strcmp(buf, "!quit") == 0)break;}printf("4. 關閉客戶端...\n");close(sockfd);return 0;
}
運行結果如下:
server端
client端