Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2776038
  • 博文数量: 505
  • 博客积分: 1552
  • 博客等级: 上尉
  • 技术积分: 2514
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-23 18:24
文章分类

全部博文(505)

文章存档

2019年(12)

2018年(15)

2017年(1)

2016年(17)

2015年(14)

2014年(93)

2013年(233)

2012年(108)

2011年(1)

2009年(11)

分类: LINUX

2014-02-14 09:59:25

socket进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。

一。创建socket服务端的流程如下:

(1)创建socket,类型为AF_LOCAL或AF_UNIX,表示用于进程通信:

  1. int server_fd;  
  2. int client_fd;//client file descriptor  
  3. struct sockaddr_un server_addr;   
  4. struct sockaddr_un client_addr;  
  5. size_t server_len,client_len;  
  6.   
  7. //cteate server socket  
  8. //delete old socket file  
  9. unlink(SERVER_NAME);  
  10. if ((server_fd = socket(AF_UNIX,  SOCK_STREAM,  0)) == -1) {  
  11.     perror("socket");  
  12.     exit(1);  
  13. }  

(2)命名socket。这里面有一个很关键的东西,socket进程通信命名方式有两种。 一是普通的命名,socket会根据此命名创建一个同名的socket文件,客户端连接的时候通过读取该socket文件连接到socket服务端。这种 方式的弊端是服务端必须对socket文件的路径具备写权限,客户端必须知道socket文件路径,且必须对该路径有读权限。另外一种命名方式是抽象命名 空间,这种方式不需要创建socket文件,只需要命名一个全局名字,即可让客户端根据此名字进行连接。后者的实现过程与前者的差别是,后者在对地址结构 成员sun_path数组赋值的时候,必须把第一个字节置0,即sun_path[0] = 0,下面用代码说明:

第一种方式:

  1.       //name the server socket   
  2. server_addr.sun_family = AF_UNIX;  
  3. strcpy(server_addr.sun_path,SERVER_NAME);  
  4. server_len = sizeof(struct sockaddr_un);  
  5. client_len = server_len;  


第二种方式:

  1. //name the socket  
  2. server_addr.sun_family = AF_UNIX;  
  3. strcpy(server_addr.sun_path, SERVER_NAME);  
  4. server_addr.sun_path[0]=0;  
  5. //server_len = sizeof(server_addr);  
  6. server_len = strlen(SERVER_NAME)  + offsetof(struct sockaddr_un, sun_path);  


其中,offsetof函数在#include 头文件中定义。因第二种方式的首字节置0,我们可以在命名字符串SERVER_NAME前添加一个占位字符串,例如:

  1. #define SERVER_NAME @socket_server  
前面的@符号就表示占位符,不算为实际名称。


或者可以把第二种方式的实现封装成一个函数:

  1. int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen)  
  2. {  
  3.     int nameLen = strlen(name);  
  4.     if (nameLen >= (intsizeof(pAddr->sun_path) -1)  /* too long? */  
  5.         return -1;  
  6.     pAddr->sun_path[0] = '\0';  /* abstract namespace */  
  7.     strcpy(pAddr->sun_path+1, name);  
  8.     pAddr->sun_family = AF_UNIX;  
  9.     *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);  
  10.     return 0;  
  11. }  

像下面这样使用这个函数:

  1. makeAddr("server_socket", &server_addr, &server_len);  

提示:客户端连接服务器的时候,必须与服务端的命名方式相同,即如果服务端是普通命名方式,客户端的地址也必须是普通命名方式;如果服务端是抽象命名方式,客户端的地址也必须是抽象命名方式。

(3)绑定并侦听

  1. bind(server_sockfd, (struct sockaddr *)&server_addr, server_len);  
  2.   
  3. //listen the server  
  4. listen(server_sockfd, 5);  

(4)等待客户端连接,并读写数据。

  1. while(1){  
  2. printf("server waiting...\n");  
  3.   
  4. //accept client connect  
  5. client_len = sizeof(client_addr);  
  6. client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_addr, &client_len);  
  7.   
  8. //read  data from client socket  
  9. read(client_sockfd, &ch, 1);  
  10. printf("read from client %d: %c",client_sockfd,ch);  
  11. ch ++;  
  12. write(client_sockfd, &ch, 1);  
  13. close(client_sockfd);  
  14. usleep(100);//1000 miliseconds = 1 second  
  15.   }  

二 socket客户端创建流程

(1)创建socket

(2)命名socket

(3)连接到服务端:

  1. //connect to server  
  2.     result = connect(sockfd, (struct sockaddr*)&address, len);  

(4)与服务端进行通信

  1. //communicate with server socket  
  2. while(1)  
  3. {  
  4.     printf("set send content:");  
  5.     scanf("%c",&ch);  
  6.     write(sockfd, &ch, 1);  
  7.     printf("send to server:%c \n",ch);  
  8.     read(sockfd, &ch, 1);  
  9.     printf("read from server: %c\n", ch);  
  10.       
  11.       
  12. }  

完整代码如下:

(1)服务端server.c:

  1. #include  
  2. #include  
  3. #include  
  4. #include  
  5. #include  
  6. #include  
  7. #include   
  8.   
  9. #define SERVER_NAME "@server_socket"  
  10. /* 
  11.  * Create a UNIX-domain socket address in the Linux "abstract namespace". 
  12.  * 
  13.  * The socket code doesn't require null termination on the filename, but 
  14.  * we do it anyway so string functions work. 
  15.  */  
  16. int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen)  
  17. {  
  18.     int nameLen = strlen(name);  
  19.     if (nameLen >= (intsizeof(pAddr->sun_path) -1)  /* too long? */  
  20.         return -1;  
  21.     pAddr->sun_path[0] = '\0';  /* abstract namespace */  
  22.     strcpy(pAddr->sun_path+1, name);  
  23.     pAddr->sun_family = AF_UNIX;  
  24.     *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);  
  25.     return 0;  
  26. }  
  27.   
  28. int main()  
  29.   
  30. {  
  31.     int server_sockfd, client_sockfd;  
  32.     socklen_t server_len, client_len;  
  33.     struct sockaddr_un server_addr;  
  34.     struct sockaddr_un client_addr;  
  35.     char ch;  
  36.     int nread;  
  37.   
  38.     //delete the old server socket  
  39.     //unlink("server_socket");  
  40.     //create socket  
  41.     server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);  
  42.   
  43.     //name the socket  
  44.     server_addr.sun_family = AF_UNIX;  
  45.     strcpy(server_addr.sun_path, SERVER_NAME);  
  46.     server_addr.sun_path[0]=0;  
  47.     //server_len = sizeof(server_addr);  
  48.     server_len = strlen(SERVER_NAME)  + offsetof(struct sockaddr_un, sun_path);  
  49.     //makeAddr("server_socket", &server_addr, &server_len);  
  50.     bind(server_sockfd, (struct sockaddr *)&server_addr, server_len);  
  51.   
  52.     //listen the server  
  53.     listen(server_sockfd, 5);  
  54.     client_sockfd = -1;  
  55.     client_len = sizeof(client_addr);  
  56.     while(1){  
  57.         printf("server waiting...\n");  
  58.         //accept client connect  
  59.         if(client_sockfd == -1){  
  60.             client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_addr, &client_len);  
  61.         }  
  62.       
  63.         //read  data from client socket  
  64.         nread = read(client_sockfd, &ch, 1);  
  65.         if(nread == 0){//client disconnected  
  66.             printf("client %d disconnected\n",client_sockfd);  
  67.             client_sockfd = -1;  
  68.         }  
  69.         else{  
  70.             printf("read from client %d: %c\n",client_sockfd,ch);  
  71.             ch ++;  
  72.             write(client_sockfd, &ch, 1);  
  73.         }  
  74.         usleep(100);//1000 miliseconds = 1 second  
  75.     }  
  76.   
  77.     return 0;  
  78.   
  79. }  

(2)客户端client.c

  1. #include  
  2. #include  
  3. #include  
  4. #include  
  5. #include  
  6. #include  
  7. #include   
  8. #define SERVER_NAME "@server_socket"  
  9. /* 
  10.  * Create a UNIX-domain socket address in the Linux "abstract namespace". 
  11.  * 
  12.  * The socket code doesn't require null termination on the filename, but 
  13.  * we do it anyway so string functions work. 
  14.  */  
  15. int makeAddr(const char* name, struct sockaddr_un* pAddr, socklen_t* pSockLen)  
  16. {  
  17.     int nameLen = strlen(name);  
  18.     if (nameLen >= (intsizeof(pAddr->sun_path) -1)  /* too long? */  
  19.         return -1;  
  20.     pAddr->sun_path[0] = '\0';  /* abstract namespace */  
  21.     strcpy(pAddr->sun_path+1, name);  
  22.     pAddr->sun_family = AF_UNIX;  
  23.     *pSockLen = 1 + nameLen + offsetof(struct sockaddr_un, sun_path);  
  24.     return 0;  
  25. }  
  26.   
  27.   
  28. int main()  
  29. {  
  30.     int sockfd;  
  31.     socklen_t len;  
  32.     struct sockaddr_un address;  
  33.     int result;  
  34.     char ch = 'A';  
  35.   
  36.     //create socket   
  37.     sockfd = socket(AF_UNIX, SOCK_STREAM, 0);  
  38.     //name the server socket  
  39.     //makeAddr("server_socket", &address, &len);  
  40.     address.sun_family = AF_UNIX;  
  41.     strcpy(address.sun_path, SERVER_NAME);  
  42.     address.sun_path[0]=0;  
  43.     //len = sizeof(address);  
  44.     len =  strlen(SERVER_NAME)  + offsetof(struct sockaddr_un, sun_path);  
  45.     //connect to server  
  46.     result = connect(sockfd, (struct sockaddr*)&address, len);  
  47.     if(result == -1)  
  48.     {  
  49.         perror("opps:client1");  
  50.         exit(1);  
  51.     }  
  52.     //communicate with server socket  
  53.     while(1)  
  54.     {  
  55.         printf("set send content:");  
  56.         scanf("%c",&ch);  
  57.         write(sockfd, &ch, 1);  
  58.         printf("send to server:%c \n",ch);  
  59.         read(sockfd, &ch, 1);  
  60.         printf("read from server: %c\n", ch);  
  61.           
  62.           
  63.     }  
  64.     exit(0);  
  65.   
  66. }  











阅读(1950) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~