免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1840 | 回复: 4
打印 上一主题 下一主题

SCOUNIX是否支持不同进程间传递描述字??? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-11-04 23:04 |只看该作者 |倒序浏览
各位大虾,帮帮忙!   

我有一个项目,需要从子进程将打开的套接字描述字传递回父进程,本来现在大多数UNIX和Linux都支持通过UNIX域套接字从一个进程将描述字传到另一个进程,在Linux上我测试没有问题,但同样的程序在SCO OpenServer5.0.5下通不过,程序告诉我不行。不知道SCO 下是否支持描述字在不同进程传递?


/* 服务进程 */
#include <stdio.h>;
#include <sys/errno.h>;
#include <sys/types.h>;
#include <sys/socket.h>;
#include <sys/un.h>;
#include <unistd.h>;
#include <sys/uio.h>;
#include <fcntl.h>;

extern int errno;
void DoDisplay( int );

void main() {

int serverfd, connfd;
struct sockaddr_un servaddr, cliaddr;
int child, clilen;

serverfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (serverfd < 0) {
    printf("parent: create socket failed!\n";
    exit(-1);
}

bzero(&servaddr, sizeof(servaddr));
servaddr.sun_family = AF_UNIX;
strcpy(servaddr.sun_path, tmpnam(NULL));

bind(serverfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(serverfd, 1024);
printf("parent: server listen at %s...\n", servaddr.sun_path);

{
        char s[200];
        sprintf(s, "echo \"./son %s\">;s.sh", servaddr.sun_path);
        system(s);
}


for (; {
    clilen = sizeof(cliaddr);
    if ( (connfd = accept(serverfd, (struct sockaddr *)&cliaddr, &clilen)) < 0)
    {
        if (errno == EINTR)
                continue;
        else
        {
                printf("parent: accept failed!\n";
                exit(-1);
        }
    }
    if ( (child = fork()) == 0) {
        printf("parent: fork one .\n";
        close(serverfd);
        DoDisplay(connfd);
        exit(0);
    }
    close(connfd);
}

}

void DoDisplay( int connfd ) {

char buf[1025];
int nbytes;
char c;
int fd;

if (read_fd(connfd, &c, 1, &fd) < 0) {
        printf("arent: read_fd failed!\n";
        exit(-1);
}

printf("parent: file %d\n", fd);
while ( (nbytes = read(fd, buf, 1024)) >; 0 ){
        printf("Read %d bytes\n", nbytes);
        buf[nbytes] = 0;
        printf("%s", buf);
}
close(connfd);
close(fd);
}

void err_quit(char *s) {
printf("%s\n", s);
exit(-1);
}

int read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
{
        struct msghdr        msg;
        struct iovec        iov[1];
        ssize_t                        n;
        int                                newfd;
#define        CMSG_SPACE(size)        (sizeof(struct cmsghdr) + (size))
#define        CMSG_LEN(size)                (sizeof(struct cmsghdr) + (size))

        union {
          struct cmsghdr        cm;
          char                                control[CMSG_SPACE(sizeof(int))];
        } control_un;
        struct cmsghdr        *cmptr;

        msg.msg_control = control_un.control;
        msg.msg_controllen = sizeof(control_un.control);

        msg.msg_name = NULL;
        msg.msg_namelen = 0;

        iov[0].iov_base = ptr;
        iov[0].iov_len = nbytes;
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;

        if ( (n = recvmsg(fd, &msg, 0)) <= 0)
                return(n);

        if ( (cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
            cmptr->;cmsg_len == CMSG_LEN(sizeof(int))) {
                if (cmptr->;cmsg_level != SOL_SOCKET)
                        err_quit("control level != SOL_SOCKET";
                if (cmptr->;cmsg_type != SCM_RIGHTS)
                        err_quit("control type != SCM_RIGHTS";
                *recvfd = *((int *) CMSG_DATA(cmptr));
        } else
                *recvfd = -1;                /* descriptor was not passed */

        return(n);
}



/* 客户进程 */
#include <stdio.h>;
#include <sys/errno.h>;
#include <sys/types.h>;
#include <sys/socket.h>;
#include <sys/un.h>;
#include <unistd.h>;
#include <sys/uio.h>;
#include <fcntl.h>;

void DoSend( int fd );
int write_fd(int fd, void *ptr, size_t nbytes, int sendfd);

void main(int argc, char **argv) {

int sockfd, ret;
struct sockaddr_un servaddr;

if (argc != 2) {
    printf("Usage: %s serverfilename \n", argv[0]);
    exit(-1);
}

sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sockfd < 0) {
        printf("son:create socket failed!\n";
        exit(-1);
}
bzero( &servaddr, sizeof(servaddr) );
servaddr.sun_family = AF_UNIX;
strcpy(servaddr.sun_path, argv[1]);
ret = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if (ret < 0) {
        printf("son: connect failed!\n";
        exit(-1);
}
DoSend(sockfd);
exit(0);
}

void DoSend( int fd ) {
int sendfd;
int n;

if ( (sendfd = open("readme", O_RDONLY)) < 0) {
        printf("son: open readme error!\n";
        exit(-1);
}
printf("son: file %d\n", sendfd);

if ( (n = write_fd(fd, "  ", 1, sendfd)) < 0)
        printf("son: write fd error!\n");
        exit(-1);

}


int write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
{
        struct msghdr        msg;
        struct iovec        iov[1];
#define        CMSG_SPACE(size)        (sizeof(struct cmsghdr) + (size))
#define        CMSG_LEN(size)                (sizeof(struct cmsghdr) + (size))

        union {
          struct cmsghdr        cm;
          char                                control[CMSG_SPACE(sizeof(int))];
        } control_un;
        struct cmsghdr        *cmptr;

        msg.msg_control = control_un.control;
        msg.msg_controllen = sizeof(control_un.control);

        cmptr = CMSG_FIRSTHDR(&msg);
        cmptr->;cmsg_len = CMSG_LEN(sizeof(int));
        cmptr->;cmsg_level = SOL_SOCKET;
        cmptr->;cmsg_type = SCM_RIGHTS;
        *((int *) CMSG_DATA(cmptr)) = sendfd;

        msg.msg_name = NULL;
        msg.msg_namelen = 0;

        iov[0].iov_base = ptr;
        iov[0].iov_len = nbytes;
        msg.msg_iov = iov;
        msg.msg_iovlen = 1;

        return(sendmsg(fd, &msg, 0));
}

论坛徽章:
0
2 [报告]
发表于 2003-11-05 00:44 |只看该作者

SCOUNIX是否支持不同进程间传递描述字???

/* 服务器 */

#include <stdio.h>;

#include <sys/socket.h>;
#include <sys/un.h>;

#include <string.h>;
#include <unistd.h>;

int main()

{ int sock,socksec;
struct sockaddr_un adresse;

int res;
int lg;
int min,max,valeur;

int nbclient = 3;
int maxfile=5;

char *fichier = "communication2";


printf("debut du serveur\n";
sock=socket(AF_UNIX,SOCK_STREAM,0);
if (sock == -1)
perror("SERVEUR: creation de la socket";
else { adresse.sun_family=AF_UNIX;
strcpy(adresse.sun_path,fichier);
lg=sizeof(adresse);
res=bind(sock,&adresse,lg);
if (res == -1)
perror("SERVEUR: liaison sur le fichier";
else { res=listen(sock,maxfile);
if (res == -1)
perror(" SERVEUR: creation de la file d'attente";
else {
printf("debut de la prise en charge des clients\n";

while (nbclient >; 0)
{ socksec=accept(sock,&adresse,&lg);
if (socksec==-1)
perror("SERVEUR: prise en charge de client";
else { printf("debut de dialogue\n";
read(socksec,&min,sizeof(int));
read(socksec,&max,sizeof(int));
printf("bornes recues %d et %d\n",min,max);
valeur=(min + max) / 2;
printf("value sended%d\n",valeur);
write(socksec,&valeur,sizeof(int));
printf("SERVEUR: fin du dialogue\n";
close(socksec);

}
nbclient--;
}

}
}
close(sock);
printf("SERVEUR: end of the program\n";
}
return(0);
}

论坛徽章:
0
3 [报告]
发表于 2003-11-05 00:45 |只看该作者

SCOUNIX是否支持不同进程间传递描述字???

/* 客户机 */

#include <stdio.h>;

#include <sys/socket.h>;
#include <sys/un.h>;

#include <string.h>;
#include <unistd.h>;  

int main()

{ int sock;
struct sockaddr_un adresse;

int res;
int lg;
int min,max,valeur;

char *fichier = "communication2";


printf("debut du client\n";
sock=socket(AF_UNIX,SOCK_STREAM,0);
if (sock == -1)
perror("CLIENT: creation de la socket";
else { printf("valeur mini SVP ? ";scanf("%d",&min);
printf("valeur maxi SVP ? ";scanf("%d",&max);

adresse.sun_family=AF_UNIX;
strcpy(adresse.sun_path,fichier);
lg=sizeof(adresse);
res=connect(sock,&adresse,lg);
if (res == -1)
perror("CLIENT: liaison sur le fichier";
else { printf("CLIENT: debut de dialogue\n";

write(sock,&min,sizeof(int));
write(sock,&max,sizeof(int));

read(sock,&valeur,sizeof(int));
printf("la valeur fournie par le serveur est %d\n",valeur);

close(sock);
printf("CLIENT: end of the client\n";
}
}
return(0);
}

论坛徽章:
0
4 [报告]
发表于 2003-11-05 23:25 |只看该作者

SCOUNIX是否支持不同进程间传递描述字???

见精华

用“描述符”查找

论坛徽章:
0
5 [报告]
发表于 2003-11-10 18:59 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP