Chinaunix首页 | 论坛 | 博客
  • 博客访问: 116867
  • 博文数量: 73
  • 博客积分: 66
  • 博客等级: 民兵
  • 技术积分: 497
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-22 14:59
文章分类

全部博文(73)

文章存档

2015年(65)

2013年(5)

2012年(3)

我的朋友

分类: LINUX

2012-11-16 12:18:51


点击(此处)折叠或打开

  1. // select 实现
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <string.h>

  6. #include <unistd.h>
  7. #include <sys/types.h> //basic system dada types
  8. #include <sys/socket.h> //basic socket definitions
  9. #include <netinet/in.h> //sockaddr_in and other defination
  10. #include <arpa/inet.h> //inet(3)functions
  11. #include <sys/select.h> //select functions

  12. #define maxline 1024

  13. void handle(int *clientsockfd, int maxfd, fd_set *rset, fd_set *pallset);

  14. int main(int argc, char **argv)
  15. {
  16.     int servport = 6887;
  17.     int listeng = 1024;

  18.     int listenfd, connfd;
  19.     struct sockaddr_in cliaddr, servaddr;
  20.     socklen_t socklen = sizeof(struct sockaddr_in);
  21.     int nread, nready;
  22.     int opt = 1;
  23.     int i;

  24.     char buf[maxline] = {0};
  25.     int client_sockfd[maxline];
  26.     fd_set allset, rset;
  27.     int maxfd;

  28.     listenfd = socket(AF_INET, SOCK_STREAM, 0);
  29.     if (listenfd < 0)
  30.     {
  31.         perror("socket");
  32.         return 1;
  33.     }
  34.     
  35.     if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0)
  36.     {
  37.         perror("setsockopt");
  38.         return 1;
  39.     }
  40. // 配置服务器网络参数
  41.     cliaddr.sin_family = AF_INET;
  42.     cliaddr.sin_port = htons(servport);
  43.     cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  44.     bzero(cliaddr.sin_zero,8);
  45.         
  46.     if (bind(listenfd, (struct sockaddr *)&cliaddr, socklen) < 0)
  47.     {
  48.         perror("bind ");
  49.         return 1;
  50.     }

  51.     if (listen(listenfd, listeng) < 0)
  52.     {
  53.         perror("listen");
  54.         return 1;
  55.     }
  56.     printf("listening...\n");
  57.        printf("max connection :%d\n", FD_SETSIZE);
  58. // 初始化文件描述符集
  59.     FD_ZERO(&allset);
  60.     FD_SET(listenfd, &allset);
  61.     maxfd = listenfd;
  62. // 将clientsockfd【】全部赋值为-1
  63.     for (i = 0; i < maxline; i++)
  64.         client_sockfd[i] = -1;
  65.     printf("echo server use select startup ,listen on port %d\n",servport);
  66.     

  67.     while(1)
  68.     {
  69.         rset = allset;
  70.         if (select(maxfd+1, &rset, NULL, NULL, NULL) < 0)
  71.         {
  72.             perror("select");
  73.             continue;
  74.         }

  75.         if (FD_ISSET(listenfd, &rset))
  76.         {
  77.             connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&socklen);
  78.             if (connfd < 0)
  79.             {
  80.                 perror("accept");
  81.                 continue;
  82.             }
  83.             printf("connect success from %s\n",inet_ntoa(cliaddr.sin_addr));
  84.             
  85.             for (i = 0; i < maxline; i++)
  86.                 if (client_sockfd[i] == -1)
  87.                 {
  88.                     client_sockfd[i] = connfd;
  89.                     break;
  90.                 }
  91.             
  92.             if (FD_SETSIZE == i)
  93.             {
  94.                 fprintf(stdout, "connection to many,more than %d\n",FD_SETSIZE);
  95.                 close(connfd);
  96.                 continue;
  97.             }

  98.             maxfd = connfd > listenfd ? connfd:listenfd;
  99.             
  100.             FD_SET(connfd, &allset);
  101.         }

  102.         handle(client_sockfd, maxfd, &rset, &allset);
  103.         sleep(1);
  104.     }

  105.     return 0;
  106. }

  107. void handle(int *clientsockfd, int maxfd, fd_set *rset, fd_set *allset)
  108. {
  109.     int nread;
  110.     int i;
  111.     char buf[maxline]={0};

  112.     for (i = 0; i < maxfd; i++)
  113.     {
  114.         if (clientsockfd[i] != -1)
  115.         {
  116.             if (FD_ISSET(clientsockfd[i], rset))
  117.             {
  118.                 nread = read(clientsockfd[i], buf, maxline);
  119.                 if (nread < 0)
  120.                 {
  121.                     perror("read");
  122.                     close(clientsockfd[i]);
  123.                     FD_CLR(clientsockfd[i],allset);
  124.                     clientsockfd[i] = -1;
  125.                     continue;
  126.                 }
  127.                 else if (nread == 0)
  128.                 {
  129.                     printf("client close the connection\n");
  130.                     close(clientsockfd[i]);
  131.                     FD_CLR(clientsockfd[i], allset);
  132.                     clientsockfd[i] = -1;
  133.                     continue;
  134.                 }
  135.                 printf("recive %s \n",buf);
  136.                 write(clientsockfd[i], buf, nread);
  137.             }
  138.             //printf("recive %s \n",buf);
  139.             //write(clientsockfd[i], buf, nread);
  140.         }
  141.     }
  142. }


点击(此处)折叠或打开

  1. // 多线程pthread
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <sys/socket.h>
  7. #include <sys/types.h> //select
  8. #include <sys/time.h> //select
  9. #include <sys/select.h> //select
  10. #include <unistd.h>
  11. #include <fcntl.h>
  12. #include <pthread.h>
  13. #include <netinet/in.h> // htonl/htons/ntohl/ntohs ...

  14. #define maxlen 128
  15. #define my_port 4525

  16. struct node
  17. {
  18.     int n_clientfd; //保存客户端描述符
  19.     struct sockaddr_in n_sin; //保存客户端地址信息
  20.     struct node *n_next; //指向下一个结构体
  21. }*head = NULL;

  22. static int count; //计总共线程数
  23. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; //初始化互斥锁
  24. pthread_cond_t cond = PTHREAD_COND_INITIALIZER; // 初始化条件变量

  25. void cleanup_handler(void *p)
  26. {
  27.     printf("pthread %d exiting...\n", count);
  28.     //free(p);
  29.     pthread_mutex_unlock(&mutex);
  30. }

  31. void pthread_handler(void *arg)
  32. {
  33.     struct node *pnode = NULL;
  34.     int client_fd;
  35.     char buf[maxlen] = {0};
  36.     char tmp[maxlen] = {0};
  37.     int i = 10; //设置读写最大次数为10次
  38.     
  39.     //fd = *(int *)arg;    
  40.     pthread_cleanup_push(cleanup_handler, pnode);
  41.     
  42.     while(1)
  43.     {
  44.         pthread_mutex_lock(&mutex);//在修改head之前,锁住,保持head数据的一致性
  45.         printf("begin to recieve data...\n");
  46.         while(NULL == head)
  47.         {
  48.             pthread_cond_wait(&cond, &mutex);
  49.         }
  50.         pnode = head;
  51.         client_fd = pnode->n_clientfd;
  52.         head = pnode->n_next; //将head置为NULL
  53.         //当不用循环时候,只能接收到一次数据,所以要用循环,不断接受数据,默认的recv。send都是阻塞的。
  54.         while(i--) //进行10次接收数据,从客户端client_fd接收数据,并向它回发数据
  55.         {
  56.             if (recv(client_fd, buf, maxlen, 0) < 0) //MSG_TRUNC 即使报文被截断, 也返回报文实际长度,recv中第三个参数为报文的最大长度,会向buf指向的内存空间写maxlen的字节数,不管是否有maxlen个字节
  57.             {
  58.             perror("recv error");
  59.             continue;
  60.             }
  61.         
  62.             printf("recv %s from %s \n", buf, inet_ntoa(pnode->n_sin.sin_addr));
  63.             // write data to client
  64.             sprintf(tmp, "hello %s ,i have recv data:%s\n", inet_ntoa(pnode->n_sin.sin_addr), buf);
  65.             send(client_fd, tmp, maxlen, 0);
  66.             memset(buf, 0x0, maxlen);
  67.             memset(tmp, 0x0, maxlen);
  68.             pthread_mutex_unlock(&mutex);//shishi
  69.             sleep(1);
  70.             //free(pnode);
  71.         }
  72.     }
  73.     pthread_cleanup_pop(0);
  74. }

  75. int main()
  76. {
  77.     struct sockaddr_in addr_server, addr_client;
  78.     char buf[maxlen] = {0};
  79.     int server_fd, client_fd[100];
  80.     int addr_client_size;
  81.     pthread_t pthread_id[100] = {0};
  82.     struct node *p;

  83.     if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  84.     {
  85.         perror("socket error");
  86.         return -1;
  87.     }
  88. // 服务器网路参数配置
  89.     addr_server.sin_family = AF_INET;
  90.     addr_server.sin_port = htons(my_port);
  91.     addr_server.sin_addr.s_addr = INADDR_ANY;
  92.     memset(addr_server.sin_zero, 0x0, 8);

  93.     if (bind(server_fd, (struct sockaddr *)&addr_server, sizeof(addr_server)) < 0)
  94.     {
  95.         perror("bind error");
  96.         return -1;
  97.     }

  98.     listen(server_fd, 10);
  99.     //pthread_create(&pthread_id, NULL, (void *)pthread_handler, &client_fd); //create pthread,创建线程应该在一个循环中,在循环外,只创建了一个线程
  100.     //在每次接到新的客户端的信息时,创建一个线程
  101.     while(1) //开始接受来自客户端的信息,并用线程接受不同客户端的信息
  102.     {
  103.         count++; //计总共线程数
  104.         if (count > 100) //客户端最大值设定为100
  105.         {
  106.             printf("over client number ,exiting\n");
  107.             break;
  108.         }
  109.     //    pthread_mutex_lock(&mutex); //
  110.         if ((client_fd[count] = accept(server_fd, (struct sockaddr*)&addr_client, &addr_client_size)) < 0)
  111.         {
  112.             perror("accept error");
  113.             continue;
  114.         }
  115.         
  116.         pthread_create(&pthread_id[count], NULL, (void *)pthread_handler, NULL); //create pthread
  117.         
  118.         p = malloc(sizeof(struct node));
  119.         pthread_mutex_lock(&mutex); //在向p写数据之前,锁住,保持head数据的一致性
  120.         p->n_clientfd = client_fd[count];
  121.         p->n_sin = addr_client;
  122.         head = p;
  123.         pthread_cond_signal(&cond);
  124.         printf("the %dth times\n", count);
  125.         pthread_mutex_unlock(&mutex);
  126.         sleep(1);
  127.         free(p);
  128.     }
  129.     printf("pthead ending--\n");
  130.     pthread_cancel(pthread_id[count]);
  131.     pthread_join(pthread_id[count], NULL);
  132.     printf("exiting all pthread-------\n");
  133.     return 0;
  134. }


点击(此处)折叠或打开

  1. // fork 多用户连接的服务器
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <sys/socket.h>
  7. #include <netdb.h>
  8. #include <netinet/in.h>
  9. #include <unistd.h>

  10. #define max_size 1024
  11. #define my_port 2597

  12. int main()
  13. {
  14.         struct sockaddr_in server_addr;
  15.         char buf[max_size] = {0};
  16.         int sockfd,client_fd;
  17.         int n;

  18.         if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  19.         {
  20.                 perror("socket");
  21.                 return 1;
  22.         }

  23.         bzero(&server_addr,sizeof(server_addr));
  24.         server_addr.sin_family = AF_INET;
  25.         server_addr.sin_port = htons(my_port);
  26.         server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  27.         
  28.         n = 1;
  29.         setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(int));

  30.         if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
  31.         {
  32.                 perror("bind");
  33.                 return 1;
  34.         }
  35.     
  36.         if (listen(sockfd, 5) == -1)
  37.         {
  38.                 perror("listen");
  39.                 return 1;
  40.         }
  41.         
  42.         printf("listening ...\n");

  43.         while (1)
  44.         {
  45.                 if ((client_fd = accept(sockfd, NULL,NULL)) == -1 && errno != EINTR)
  46.                     continue;
  47.                 
  48.                 printf("------------------\n");
  49.                 if ((n = fork()) == 0)
  50.                 {
  51.                         while (1)
  52.                         {
  53.                             if (read(client_fd, buf, max_size) == -1)
  54.                             {
  55.                                     perror("recv");
  56.                                     return 1;
  57.                             }

  58.                             printf("recieve data: %s\n",buf);
  59.                             memset(buf,0x0,1024);
  60.                         }

  61.                         close(client_fd);
  62.                         close(sockfd);
  63.                         exit(0);
  64.                 }
  65.                 else close(client_fd);
  66.         }
  67. }

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