- 浏览: 258118 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
ab0809:
写的很好,谢谢
c++中的 extern "C" -
eieihihi:
说得太好了,我就喜欢这种很透彻的说法
c++中的 extern "C" -
infollllll:
package com;import java.io.*;im ...
websocket通讯协议(10版本)简介 -
rocksent:
websocket draft10握手成功了,可是传数据一直失 ...
websocket通讯协议(10版本)简介 -
guanbeilang:
通过你的代码,学会了怎么从客户端接收消息,并改造成了nodej ...
websocket通讯协议(10版本)简介
UNIX domain socket传递文件描述符
- 博客分类:
- c
c版本(UNIX高级编程中的例子):
// sendmsg.h #ifndef SENDMSG_H #define SENDMSG_H #include <sys/types.h> int send_fd(int fd, int fd_to_send); int recv_fd(int fd, ssize_t (*userfunc)(int, const void*, size_t)); #endif
// semdmsg.c #include "sendmsg.h" #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> static struct cmsghdr* cmptr = NULL; static int CONTROLLEN = sizeof(struct cmsghdr) + sizeof(int); static int MAXLINE = 100; int send_fd(int fd, int fd_to_send) { struct iovec iov[1]; struct msghdr msg; char buf[2]; iov[0].iov_base = buf; iov[0].iov_len = 2; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; if (fd_to_send <= 0) { return -1; } if (cmptr == NULL && (cmptr = (struct cmsghdr*)malloc(CONTROLLEN)) == NULL) return -1; cmptr->cmsg_level = SOL_SOCKET; cmptr->cmsg_type = SCM_RIGHTS; cmptr->cmsg_len = CONTROLLEN; msg.msg_control = cmptr; msg.msg_controllen = CONTROLLEN; *(int*)CMSG_DATA(cmptr) = fd_to_send; buf[1] = 0; buf[0] = 0; if (sendmsg(fd, &msg, 0) != 2) return -1; return 0; } int recv_fd(int fd, ssize_t (*userfunc)(int, const void*, size_t)) { int newfd, nr, status; char *ptr; char buf[MAXLINE]; struct iovec iov[1]; struct msghdr msg; status = -1; for ( ; ; ) { iov[0].iov_base = buf; iov[0].iov_len = sizeof(buf); msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; if (cmptr == NULL & (cmptr = (struct cmsghdr*)malloc(CONTROLLEN)) == NULL) { return -1; } msg.msg_control = cmptr; msg.msg_controllen = CONTROLLEN; if ((nr = recvmsg(fd, &msg, 0)) < 0) { // err_sys("recvmsg error"); } else if (nr == 0) { // err_ret("connection closed by server"); return -1; } for (ptr = buf; ptr < &buf[nr]; ) { if (*ptr++ == 0) { if (ptr != &buf[nr-1]) { // err_dump("message format error"); } status = *ptr & 0xFF; if (status == 0) { if (msg.msg_controllen != CONTROLLEN) { // err_dump("status = 0but no fd"); } newfd = *(int*)CMSG_DATA(cmptr); } else { newfd = -status; } nr -= 2; } } // if (nr > 0 && (&userfunc)(STDERR_FILENO, buf, nr) != nr) // { // return -1; // } if (status >= 0) return newfd; } }
c++版本,自己封装的:
//domainsocket.h /* * domainsocket.h * * Created on: Apr 13, 2012 * Author: song */ #ifndef DOMAINSOCKET_H_ #define DOMAINSOCKET_H_ #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/un.h> #include <arpa/inet.h> #include <netinet/in.h> #include <unistd.h> #include <errno.h> #include <sys/stat.h> #include <fcntl.h> class DomainSocket { // the exact name of this class may be "DomainSocketListener" // but we call it "DomainSocket" temporary public: DomainSocket(); virtual ~DomainSocket(); int Bind(const char* path); int Listen(int n); int Accept(); int Connect(const char* path); // client call this to send data int Send(const void* buf, size_t len, int flags); // server call this to send data int Send(int sockfd, const void* buf, size_t len, int flags); // client receive int Recv(void *buf, size_t len, int flags); // server receive int Recv(int sockfd, void *buf, size_t len, int flags); /* * the four methods below used to send and receive file descriptor. * if you are server, you have one more argument than client whatever * send or receive. * */ // send file descriptor // domain socket client send fd need call this. int Sendfd(int fdToSend); // domain socket server send fd need call this. int Sendfd(int sockfd, int fdToSend); // received file descriptor as return value // return : // > 0 all right! // = 0 receive fail int Recvfd(); // received file descriptor as return value // ... ... ... ... int Recvfd(int sockfd); protected: void DelDSocketFilePath(); private: int m_fd; struct sockaddr_un m_addr; const char* m_path; struct cmsghdr* cmptr; int CONTROLLEN; int MAXLINE; int _Sendfd(int sockfd, int fdToSend); int _Recvfd(int sockfd); }; #endif /* DOMAINSOCKET_H_ */
//domainsocket.cpp #include "domainsocket.h" using namespace std; DomainSocket::DomainSocket() { m_fd = 0; m_path = NULL; cmptr = NULL; CONTROLLEN = sizeof(struct cmsghdr) + sizeof(int); MAXLINE = 100; ////////////////////////////////// int len; memset(&m_addr, 0, sizeof(m_addr)); if ((m_fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { cout<<"create domain socket fail!"<<endl; // return -1; } cout<<"create domain socket ... , fd is '"<<m_fd<<"'"<<endl; } DomainSocket::~DomainSocket() { close(m_fd); DelDSocketFilePath(); } int DomainSocket::Bind(const char* path) { m_path = path; // if file exist delete it DelDSocketFilePath(); m_addr.sun_family = AF_UNIX; strcpy(m_addr.sun_path, (char*)m_path); // bind if (bind(m_fd, (struct sockaddr*)&m_addr, sizeof(m_addr)) < 0) { cout<<"domain bind fail!, errno is '"<<errno<<"' [reason:" <<strerror(errno)<<"]"<<endl; close(m_fd); DelDSocketFilePath(); return -1; } cout<<"domain bind (socket and sockaddr) ..."<<endl; return 0; } int DomainSocket::Listen(int n) { if (listen(m_fd, n) < 0) { cout<<"domain listen fail!, errno is '"<<errno<<"' [reason:" <<strerror(errno)<<"]"<<endl; close(m_fd); DelDSocketFilePath(); return -1; } cout<<"domain listen ..."<<endl; return 0; } int DomainSocket::Accept() { struct sockaddr cli_addr; int new_fd; int len = sizeof(cli_addr); if ((new_fd = accept(m_fd, (struct sockaddr*)&cli_addr, (socklen_t*)&len)) < 0) { cout<<"domain accept fail!, errno is '"<<errno<<"' [reason:"<<strerror(errno)<<"]"<<endl; close(m_fd); DelDSocketFilePath(); return -1; } cout<<" domain accept a new fd '"<<new_fd<<"'"<<endl; return new_fd; } int DomainSocket::Connect(const char* path) { sockaddr_un server_addr; server_addr.sun_family = AF_UNIX; strcpy(server_addr.sun_path, path); if (connect(m_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { cout<<"connect fail, err msg: "<<strerror(errno)<<endl; close(m_fd); return -1; } } int DomainSocket::Send(const void *buf, size_t len, int flags) { return send(m_fd, buf, len, flags); } int DomainSocket::Send(int sockfd, const void *buf, size_t len, int flags) { return send(sockfd, buf, len, flags); } int DomainSocket::Recv(void *buf, size_t len, int flags) { return recv(m_fd, buf, len, flags); } int DomainSocket::Recv(int sockfd, void *buf, size_t len, int flags) { return recv(sockfd, buf, len, flags); } int DomainSocket::Sendfd(int fdToSend) { return _Sendfd(m_fd, fdToSend); } int DomainSocket::Sendfd(int sockfd, int fdToSend) { return _Sendfd(sockfd, fdToSend); } int DomainSocket::Recvfd() { return _Recvfd(m_fd); } int DomainSocket::Recvfd(int sockfd) { return _Recvfd(sockfd); } int DomainSocket::_Sendfd(int sockfd, int fdToSend) { struct iovec iov[1]; struct msghdr msg; char buf[2]; iov[0].iov_base = buf; iov[0].iov_len = 2; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; if (fdToSend <= 0) { return -1; } if (cmptr == NULL && (cmptr = (struct cmsghdr*)malloc(CONTROLLEN)) == NULL) return -1; cmptr->cmsg_level = SOL_SOCKET; cmptr->cmsg_type = SCM_RIGHTS; cmptr->cmsg_len = CONTROLLEN; msg.msg_control = cmptr; msg.msg_controllen = CONTROLLEN; *(int*)CMSG_DATA(cmptr) = fdToSend; buf[1] = 0; buf[0] = 0; if (sendmsg(sockfd, &msg, 0) != 2) return -1; return 0; } int DomainSocket::_Recvfd(int sockfd) { int newfd, nr, status; char *ptr; char buf[MAXLINE]; struct iovec iov[1]; struct msghdr msg; status = -1; for ( ; ; ) { iov[0].iov_base = buf; iov[0].iov_len = sizeof(buf); msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_name = NULL; msg.msg_namelen = 0; if (cmptr == NULL & (cmptr = (struct cmsghdr*)malloc(CONTROLLEN)) == NULL) { return -1; } msg.msg_control = cmptr; msg.msg_controllen = CONTROLLEN; if ((nr = recvmsg(sockfd, &msg, 0)) < 0) { // err_sys("recvmsg error"); } else if (nr == 0) { // err_ret("connection closed by server"); return -1; } for (ptr = buf; ptr < &buf[nr]; ) { if (*ptr++ == 0) { if (ptr != &buf[nr-1]) { // err_dump("message format error"); } status = *ptr & 0xFF; if (status == 0) { if (msg.msg_controllen != CONTROLLEN) { // err_dump("status = 0but no fd"); } newfd = *(int*)CMSG_DATA(cmptr); } else { newfd = -status; } nr -= 2; } } // if (nr > 0 && (&userfunc)(STDERR_FILENO, buf, nr) != nr) // { // return -1; // } if (status >= 0) return newfd; } } void DomainSocket::DelDSocketFilePath() { if (!m_path) return; unlink(m_path); }
发表评论
-
c++ vector list map在遍历中删除元素
2013-05-07 14:47 5004c++ STL 中的vector, list, map ... -
c++ 构造函数和析构函数调用顺序
2013-04-25 16:54 1145#include <iostream> ... -
epoll高效的原因
2013-03-18 11:10 1000epoll高效的原因: 使用内核中断实现,中断后调用 ... -
unix domain socket传递描述符
2012-04-25 15:18 934用unix domain socket在进程间传递描述符。 ... -
C++中的虚函数和虚函数表
2012-04-02 18:17 927请看这一篇文章: http://hi.baidu.com/w ... -
c++中函数参数返回值用string好还是const char *好
2012-02-01 07:38 9771有这样一个函数test需要两个字符串作为参数,那么test的原 ... -
google的gtest测试框架
2011-12-21 18:17 824http://www.cnblogs.com/coderzh/ ... -
windows下TCP通讯
2011-12-20 18:17 1014客户端 #include <iostream> ... -
静态库与共享库
2011-11-01 19:00 1683在用c c++编程时经常用到库,库有静态的,和共享 ... -
c++线程池
2011-09-26 09:17 779 -
websocket通讯协议(10版本)简介
2011-09-22 18:27 15006前言: 工作中用到 ... -
epoll服务器
2011-09-21 22:33 771epoll服务器。 ... -
c,c++ little knowledge
2011-08-31 15:00 6381. 把一个string型字符串全部转成小写。 ... -
c++中的拷贝构造函数
2011-07-14 16:44 1072int a = 2; int b = a; ... -
简单的tcp通讯
2011-07-12 14:55 853简单的tcp通讯例子。 server端 /* ... -
c++中的 extern "C"
2011-06-21 20:33 23676比如说你用C 开发 ... -
c语言操作mysql数据库(Ubuntu11.04)
2011-06-11 17:43 2890系统:Ubuntu11.04 1.刚安装 ... -
全局宏定义
2010-12-22 22:59 5448首先我们要理解定义和声明的区别,举个常见的例子,比 ...
相关推荐
NULL 博文链接:https://songpengfei.iteye.com/blog/1498087
它提供了一个简单的页面来建立 Unix domain socket 来接收来自 libafdt 服务器中的文件描述请求或者是传输文件描述信息到客户端。通过底层和同步接口传输数据报的时候需要使用 libevent。libafdt 有两个高层接口:...
sockfd:是由socket调用返回的文件描述符. addrlen:是 sockaddr结构的长度. my_addr:是一个指向 sockaddr的指针. 在<linux/socket.h>;中有 sockaddr的定义 struct sockaddr{ unisgned short as_family; char ...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
第18章 Unix域协议:I/O和描述符的传递 18.1 概述 18.2 PRU_SEND和PRU_RCVD请求 18.3 描述符的传递 18.4 unp_internalize函数 18.5 unp_externalize函数 18.6 unp_discard函数 18.7 unp_dispose函数 18.8 unp_scan...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
第18章 Unix域协议:I/O和描述符的传递 210 18.1 概述 210 18.2 PRU_SEND和PRU_RCVD请求 210 18.3 描述符的传递 214 18.4 unp_internalize函数 218 18.5 unp_externalize函数 220 18.6 unp_discard函数 221 18.7 unp...
27.3.4 异常中止一个文件的传输: Telnet同步信号 326 27.3.5 匿名FTP 329 27.3.6 来自一个未知IP地址的匿名FTP 330 27.4 小结 331 第28章 SMTP:简单邮件传送协议 332 28.1 引言 332 28.2 SMTP协议 332 28.2.1 简单...
27.3.4 异常中止一个文件的传输: Telnet同步信号 326 27.3.5 匿名FTP 329 27.3.6 来自一个未知IP地址的匿名FTP 330 27.4 小结 331 第28章 SMTP:简单邮件传送协议 332 28.1 引言 332 28.2 SMTP协议 332 28.2.1 简单...
27.3.4 异常中止一个文件的传输: Telnet同步信号 326 27.3.5 匿名FTP 329 27.3.6 来自一个未知IP地址的匿名FTP 330 27.4 小结 331 第28章 SMTP:简单邮件传送协议 332 28.1 引言 332 28.2 SMTP协议 332 28.2.1 简单...
27.3.4 异常中止一个文件的传输: Telnet同步信号 326 27.3.5 匿名FTP 329 27.3.6 来自一个未知IP地址的匿名FTP 330 27.4 小结 331 第28章 SMTP:简单邮件传送协议 332 28.1 引言 332 28.2 SMTP协议 332 28.2.1 简单...
27.3.4 异常中止一个文件的传输: Telnet同步信号 326 27.3.5 匿名FTP 329 27.3.6 来自一个未知IP地址的匿名FTP 330 27.4 小结 331 第28章 SMTP:简单邮件传送协议 332 28.1 引言 332 28.2 SMTP协议 332 28.2.1 简单...