进程笔记2:进程之间的通信(UNIX域套接字socket) .
来源:互联网 发布:mac xquartz 编辑:程序博客网 时间:2024/05/20 01:35
socket的地址数据结构根据不同的系统以及网络环境有不同形式。为了使不同格式地址能够被传入套接字函数,必须强制将地址结构转换为:
- struct sockaddr{
- sa_family_t sa_family; /* address family*/
- char sa_data[]; /* variable-length address*/
- ...
- };
struct sockaddr{ sa_family_t sa_family; /* address family*/ char sa_data[]; /* variable-length address*/ ...};
套接字实现可以自由地添加额外的成员并且定义sa_data成员的大小。例如在linux中,该结构定义如下
- struct sockaddr{
- sa_family_t sa_family; /* address family*/
- char sa_data[14]; /* variable-length address*/
- };
struct sockaddr{ sa_family_t sa_family; /* address family*/ char sa_data[14]; /* variable-length address*/};
其中sa_family_t表示套接字的通信域。主要有以下四个值
创建套接字的函数如下
- #include <sys/socket.h>
- int socket(int domain, int type, int protocol);/*成功返回文件(套接字)描述符,出错返回-1
#include <sys/socket.h>int socket(int domain, int type, int protocol);/*成功返回文件(套接字)描述符,出错返回-1
其中domain指代通信域,type指代套接字类型,主要有以下四种类型描述SOCK_DGRAM长度固定的、无连接的不可靠报文传递SOCK_RAMIP协议的数据报接口SOCK_SEQPACKET长度固定、有序、可靠的面向连接报文传递SOCK_STREAM有序、可靠、双向的面向连接字节流
参数protocol通常是零,表示按给定的域和套接字类型选择默认协议。当对同一域和套接字类型支持多个协议时,可以使用protocol参数选择一个特定协议。
一个多进程间利用UNIX域套接字(只用在本地)进行通信的例子(代码分两部分不方便观察,后面socket_unix.c将其合为了一部分)
- /*
- domain_socket.h
- @Author: duanjigang @2006-4-11
- @Desp: declaratin of methods used for unix-domain-socket communication
- */
- #ifndef _H_
- #define _H_
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/un.h>
- #include <sys/socket.h>
- #define MSG_SIZE 1024
- int init_send_socket(struct sockaddr_un * addr,char * path)
- {
- int sockfd,len;
- sockfd=socket(AF_UNIX,SOCK_DGRAM,0);
- if(sockfd<0)
- {
- exit(1);
- }
- bzero(addr,sizeof(struct sockaddr_un));
- addr->sun_family=AF_UNIX;
- strcpy(addr->sun_path,path);
- return sockfd;
- }
- int init_recv_socket(char * path)
- {
- int sockfd,len;
- struct sockaddr_un addr;
- sockfd=socket(AF_UNIX,SOCK_DGRAM,0);
- if(sockfd<0)
- {
- return -1;
- }
- bzero(&addr,sizeof(struct sockaddr_un));
- addr.sun_family = AF_UNIX;
- strcpy(addr.sun_path, path);
- unlink(path);
- len = strlen(addr.sun_path) + sizeof(addr.sun_family);
- if(bind(sockfd,(struct sockaddr *)&addr,len)<0)
- {
- return -1;
- }
- return sockfd;
- }
- int receive_from_socket(int sockfd, char msg[])
- {
- int n;
- memset(msg, 0, MSG_SIZE);
- n=recvfrom(sockfd, msg, MSG_SIZE, 0, NULL, NULL);
- if(n<=0)
- {
- return -1;
- }
- msg[n]=0;
- return n;
- }
- int send_to_socket(int sockfd, char msg[], const struct sockaddr_un * addr)
- {
- int len;
- len = strlen(addr->sun_path)+sizeof(addr->sun_family);
- sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr*)addr,len);
- return 1;
- }
- #endif
/*domain_socket.h@Author: duanjigang @2006-4-11@Desp: declaratin of methods used for unix-domain-socket communication */#ifndef _H_#define _H_#include <stdio.h>#include <unistd.h>#include <sys/un.h>#include <sys/socket.h>#define MSG_SIZE 1024int init_send_socket(struct sockaddr_un * addr,char * path){ int sockfd,len; sockfd=socket(AF_UNIX,SOCK_DGRAM,0); if(sockfd<0) { exit(1); } bzero(addr,sizeof(struct sockaddr_un)); addr->sun_family=AF_UNIX; strcpy(addr->sun_path,path); return sockfd;}int init_recv_socket(char * path){ int sockfd,len; struct sockaddr_un addr; sockfd=socket(AF_UNIX,SOCK_DGRAM,0); if(sockfd<0) { return -1; } bzero(&addr,sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strcpy(addr.sun_path, path); unlink(path); len = strlen(addr.sun_path) + sizeof(addr.sun_family); if(bind(sockfd,(struct sockaddr *)&addr,len)<0) { return -1; } return sockfd;}int receive_from_socket(int sockfd, char msg[]){ int n; memset(msg, 0, MSG_SIZE); n=recvfrom(sockfd, msg, MSG_SIZE, 0, NULL, NULL); if(n<=0) { return -1; } msg[n]=0; return n;}int send_to_socket(int sockfd, char msg[], const struct sockaddr_un * addr){ int len; len = strlen(addr->sun_path)+sizeof(addr->sun_family); sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr*)addr,len); return 1;}#endif
- /*
- main.c
- @Author: duanjigang @ 2006-4-11
- @Desp: Two processes communicate with unix domain socket
- */
- #include "domain_socket.h"
- #define PATH "/home/useless"
- /*
- 进程间通过域进行通讯-举例:父子进程,一个发送,一个接收
- */
- int main(void)
- {
- int pid;
- /*
- 子进程用于发送消息
- */
- if((pid = fork()) == 0)
- {
- int fd, counter = 0;
- char send_buffer[MSG_SIZE];
- struct sockaddr_un addr;
- if( (fd = init_send_socket(&addr, PATH)) > 0)
- while(1)
- {
- memset(send_buffer, 0 , MSG_SIZE);
- /*
- 防止计数器越界,所以做一个复位判断
- */
- sprintf(send_buffer,"message for %d times",counter++ >= 10000 ? 1 : counter);
- send_to_socket(fd, send_buffer, &addr);
- printf("Sender: %s\n", send_buffer);
- sleep(1);
- }
- }/*
- 父进程用于接收消息
- */
- else
- {
- int fd;
- char recv_buffer[MSG_SIZE];
- if( (fd = init_recv_socket(PATH))> 0)
- while(1)
- {
- memset(recv_buffer, 0, MSG_SIZE);
- if(receive_from_socket(fd, recv_buffer))
- {
- printf("Receiver: %s\n", recv_buffer);
- }
- }
- }
- }
/*main.c@Author: duanjigang @ 2006-4-11@Desp: Two processes communicate with unix domain socket*/#include "domain_socket.h"#define PATH "/home/useless"/*进程间通过域进行通讯-举例:父子进程,一个发送,一个接收*/int main(void){ int pid; /* 子进程用于发送消息 */ if((pid = fork()) == 0) { int fd, counter = 0; char send_buffer[MSG_SIZE]; struct sockaddr_un addr; if( (fd = init_send_socket(&addr, PATH)) > 0) while(1) { memset(send_buffer, 0 , MSG_SIZE); /* 防止计数器越界,所以做一个复位判断 */ sprintf(send_buffer,"message for %d times",counter++ >= 10000 ? 1 : counter); send_to_socket(fd, send_buffer, &addr); printf("Sender: %s\n", send_buffer); sleep(1); } }/* 父进程用于接收消息 */ else { int fd; char recv_buffer[MSG_SIZE]; if( (fd = init_recv_socket(PATH))> 0) while(1) { memset(recv_buffer, 0, MSG_SIZE); if(receive_from_socket(fd, recv_buffer)) { printf("Receiver: %s\n", recv_buffer); } } }}
运行结果示例:
- Sender: message for 1 times
- Sender: message for 2 times
- Receiver: message for 2 times
- Sender: message for 3 times
- Receiver: message for 3 times
- Sender: message for 4 times
- Receiver: message for 4 times
- Sender: message for 5 times
- Receiver: message for 5 times
Sender: message for 1 timesSender: message for 2 timesReceiver: message for 2 timesSender: message for 3 timesReceiver: message for 3 timesSender: message for 4 timesReceiver: message for 4 timesSender: message for 5 timesReceiver: message for 5 times
socket_unix.c
- //利用UNIX域套接字通信
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/un.h>
- #include <sys/socket.h>
- #define MSG_MAX_SIZE 1024
- #define PATH "a.socket"//套接字文件
- int main()
- {
- int len;
- int socket_fd;
- struct sockaddr_un addr;
- bzero(&addr, sizeof(struct sockaddr_un));
- addr.sun_family = AF_UNIX;
- strcpy(addr.sun_path, PATH);
- len = strlen(addr.sun_path)+sizeof(addr.sun_family);
- if(!fork())//子进程内部代码
- {
- int counter = 0;
- char send_buffer[MSG_MAX_SIZE];
- //init send socket
- socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
- if(socket_fd<0)
- {
- printf("client socket error!");
- return 0;
- }
- while(1) //循环发送数据消息
- {
- memset(send_buffer, 0, MSG_MAX_SIZE);
- sprintf(send_buffer, "message for %d times", counter++);
- //将数据信息发送到addr指定的套接字文件之中,所以这样进程之间就可以进行通信
- sendto(socket_fd, send_buffer, strlen(send_buffer), 0, (struct sockaddr*)&addr, len);
- printf("sender:%s\n", send_buffer);
- sleep(1);
- }
- }
- else
- {
- char recv_buffer[MSG_MAX_SIZE];
- //init recv socket
- socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
- if(socket_fd<0)
- {
- printf("server socket error!");
- return 0;
- }
- unlink(PATH);//防止要创建的socket文件已存在
- if(bind(socket_fd, (struct sockaddr *)&addr, len)<0)//只有bind以后才会在硬盘创建套接字PATH
- {
- printf("bind error");
- return 0;
- }
- while(1)//循环接收数据
- {
- memset(recv_buffer, 0, MSG_MAX_SIZE);
- //receive from socket从指定socket中读取数据,这里socket已经绑定了指定的PATH的文件
- recvfrom(socket_fd, recv_buffer, MSG_MAX_SIZE, 0, NULL, NULL);
- printf("receive Message: %s\n", recv_buffer);
- }
- }
- return 0;
- }
- 进程笔记2:进程之间的通信(UNIX域套接字socket)
- 进程笔记2:进程之间的通信(UNIX域套接字socket)
- 进程笔记2:进程之间的通信(UNIX域套接字socket) .
- 进程间通信(六):unix域套接字
- 进程之间的通信--套接字(网络部分)
- unix进程间通信方式(下)-unix域套接字
- Linux高级进程间通信:UNIX域套接字
- unix域套接字-高级进程间通信
- Understanding Unix/Linux Programming 笔记:chapter 11:连接到近端或远端的进程:服务器与Socket(套接字)
- linux进程间通信--socket套接字
- linux进程间通信--socket套接字
- linux进程间通信--socket套接字
- 进程间通信(11) - 网络套接字(socket)[2]
- Linux进程间套接字(Socket)通信
- Linux进程间通信-----使用数据报套接字实现两个进程之间的通信
- 进程通信:管道(pipe)和 unix域套接字(socketpair)区别
- 进程通信:管道(pipe)和 unix域套接字(socketpair)区别
- 进程间通信的例子: socket unix
- 关于windows下IDA远程调试linux
- htmlparser爬虫实现网页上的图片下载
- 马克思 第一章 世界的物质性及其发展规律
- 曾用心并深度参与的一款游戏今天发布了关服通知,回顾一下我最初的工作日报
- 马克思 第二章 认识世界和改造世界
- 进程笔记2:进程之间的通信(UNIX域套接字socket) .
- android 特效之一 电视机关闭特效
- 使用 AF_UNIX 地址系列的服务器应用程序
- gawk的使用方法
- 网关服务器 .
- gcc 优化选项 -O1 -O2 -O3 -Os 优先级,-fomit-frame-pointer
- 使用非递归与递归来判断回文
- 闪客工具 收集一下网上有意思的方法
- Linux 进程互斥量