Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1176992
  • 博文数量: 573
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 66
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-28 16:21
文章分类

全部博文(573)

文章存档

2018年(3)

2016年(48)

2015年(522)

分类: LINUX

2015-12-02 15:31:27


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>
  7. #include <sys/wait.h>
  8. #include <pthread.h>
  9. #include <stdlib.h>
  10. #include <time.h>
  11. #include <unistd.h>
  12. #include <sys/stat.h>
  13. #include <fcntl.h>
  14. #include <errno.h>
  15. #include <termios.h>
  16. #include <sys/time.h>
  17. #include <sys/timeb.h>
  18. #include <stdarg.h>

  19. #define MAXTIME 1024
  20. //#define SER_IP "169.254.130.128" /*服务器的IP地址*/
  21. #define SER_IP "192.168.152.128" /*服务器的IP地址*/

  22. int read_socket(int socket_id, char *pbuf, int len);
  23. int write_socket(int socket_id, char *pbuf, int len);

  24. int main(int argc, char ** argv) /*客户端程序*/
  25. {
  26.     
  27.     fd_set readset;
  28.     fd_set writeset;
  29.     int txtfd;
  30.     int maxfdp;
  31.     
  32.     char judg[32];
  33.     char readbuf[1024];
  34.     char total_buf[1024];
  35.     int sockfd = -1;
  36.     int ret = -1;
  37.     int opt = 1;
  38.     int len1, len2;
  39.     struct sockaddr_in seraddr; /*用来存放要访问的服务器的IP地址和端口号*/
  40.     //struct timeval timeout={3,0};
  41.     
  42.     struct timeval timeout;
  43.     timeout.tv_sec=5;
  44.     timeout.tv_usec=0;
  45.     
  46.     memset(judg, 0, sizeof(judg));
  47.     memset(readbuf, 0, sizeof(readbuf));
  48.     memset(total_buf, 0, sizeof(total_buf));
  49.     memset(&seraddr, 0, sizeof(seraddr)); /*初始化*/
  50.     
  51.     txtfd = open("./select.txt", O_RDWR);
  52.     if(txtfd < 0)
  53.     {
  54.             printf("open err!\n");
  55.             exit(-1);
  56.     }
  57.     
  58.     sockfd = socket(AF_INET, SOCK_STREAM, 0); /*创建套接字文件,TCP协议*/
  59.     if(sockfd < 0)
  60.     {
  61.         return -1;
  62.     }

  63.     seraddr.sin_family = AF_INET; /*服务器的地址族协议*/
  64.     seraddr.sin_port = htons(4989);     /*服务器的端口号*/
  65.     inet_pton(AF_INET, SER_IP, &seraddr.sin_addr.s_addr); /*服务器的ip地址*/
  66.                                                                                                             
  67.     ret = connect_retry(sockfd, (struct sockaddr*)&seraddr, sizeof(seraddr)); /*请求连接服务器*/
  68.     if(ret < 0)
  69.     {
  70.         printf("connect_retry err!\n");
  71.         return -1;
  72.     }
  73.     
  74.     printf("客户端已请求连接!\n");
  75.     
  76.     char    serv_ip[20];
  77.     char    guest_ip[20];
  78.   struct sockaddr_in serv;
  79.   struct sockaddr_in guest;
  80.   socklen_t serv_len = sizeof(serv);
  81.   socklen_t guest_len = sizeof(guest);

  82.   getsockname(sockfd, (struct sockaddr *)&guest, &guest_len);
  83.   getpeername(sockfd, (struct sockaddr *)&serv, &serv_len);

  84.   inet_ntop(AF_INET, &guest.sin_addr, guest_ip, sizeof(guest_ip));
  85.   inet_ntop(AF_INET, &serv.sin_addr, serv_ip, sizeof(serv_ip));
  86.   printf("服务端IP和PORT[%s]:[%d]\n", serv_ip, ntohs(serv.sin_port));
  87.   printf("客户端IP和PORT[%s]:[%d]\n", guest_ip, ntohs(guest.sin_port));
  88.   
  89.   printf("close(sockfd) begin:\n");
  90.   write(sockfd, "wangxc", strlen("wangxc"));
  91.   //close(sockfd);
  92.   printf("close(sockfd) ok!\n");
  93.     while(1);
  94.     
  95.     while(1)
  96.     {
  97.             printf("***********************************************\n");
  98.             
  99.             sleep(5);
  100.             FD_ZERO(&readset);
  101.             FD_ZERO(&writeset);
  102.             
  103.             FD_SET(sockfd, &readset); //添加描述符
  104.             FD_SET(txtfd, &readset); //添加描述符
  105.             FD_SET(sockfd, &writeset); //添加描述符
  106.             FD_SET(txtfd, &writeset); //添加描述符
  107.             
  108.             maxfdp = sockfd > txtfd ? sockfd+1 : txtfd+1;
  109.             printf("sockfd=[%d]\n", sockfd);
  110.             printf("txtfd=[%d]\n", txtfd);
  111.             printf("maxfdp=[%d]\n", maxfdp);

  112.             ret = select(maxfdp, &readset, &writeset, NULL, &timeout);
  113.             printf("select ret = [%d]\n", ret);
  114.             switch(ret)
  115.             {
  116.                     case 0:
  117.                     {
  118.                             printf("已经超时,没有描述符准备好!\n");
  119.                             break; //再次轮循
  120.                     }
  121.                     case (-1):
  122.                     {
  123.                             printf("select err!\n");
  124.                             exit(-1);
  125.                     }
  126.                     default:
  127.                     {
  128.                             ret = FD_ISSET(sockfd, &readset);
  129.                             printf("FD_ISSET ret=[%d]\n", ret);
  130.                             if(ret == 1) //sockfd读准备好:即网络上有数据
  131.                             {
  132.                                         printf("sockfd 可读!\n");
  133.                                         memset(readbuf, 0, sizeof(readbuf));
  134.                                         read(sockfd, readbuf, sizeof(readbuf)); /*对服务器是否准备好的判断*/
  135.                                         printf("客户端接受数据:[%s]\n", readbuf);
  136.                                         ret = FD_ISSET(txtfd, &writeset);
  137.                                         if(ret == 1)
  138.                                         {
  139.                                                 write(txtfd, readbuf, strlen(readbuf));
  140.                                         }
  141.                             }
  142.                             else //sockfd读没准备好:即网络上还没有数据
  143.                             {
  144.                                     printf("sockfd 读会阻塞!\n");
  145.                             }
  146.                             
  147.                             ret = FD_ISSET(sockfd, &writeset);
  148.                             printf("FD_ISSET ret=[%d]\n", ret);
  149.                             if(ret == 1) //sockfd写准备好
  150.                             {
  151.                                         printf("sockfd 可写!\n");
  152.                             }
  153.                             ret = FD_ISSET(txtfd, &readset);
  154.                             printf("FD_ISSET ret=[%d]\n", ret);
  155.                             if(ret == 1)
  156.                             {
  157.                                         printf("txtfd 可读!\n");
  158.                             }
  159.                             ret = FD_ISSET(txtfd, &writeset);
  160.                             printf("FD_ISSET ret=[%d]\n", ret);
  161.                             if(ret == 1)
  162.                             {
  163.                                         printf("txtfd 可写!\n");
  164.                             }
  165.                     }
  166.             }
  167.             
  168.     }
  169.     
  170.     close(sockfd);
  171.     return 0;
  172. }



  173. /***********************************************************
  174. * 函 数 名:connect_retry
  175. * 功能描述: 瞬时connect错误,支持重试的连接
  176. * 输入参数:
  177. * 输出参数:
  178. * 返 回:
  179. * 流程描述:
  180. * 说明:
  181. * 修改记录:
  182. * [修改人] [日期] - [描述]
  183. ***********************************************************/
  184. int connect_retry(int sockfd, const struct sockaddr * addr, socklen_t len)
  185. {
  186.     int time;
  187.     for(time = 1; time <= MAXTIME; time <<= 1)
  188.     {
  189.         if(connect(sockfd, addr, len) == 0)
  190.         {
  191.             return 0;
  192.         }
  193.         if(time <= MAXTIME/2)
  194.         {
  195.             printf("connect失败,睡眠[%d]秒\n", time);
  196.             sleep(time);
  197.         }
  198.     }
  199.     return -1;
  200. }


  201. /***********************************************************
  202. * 函 数 名:read_socket
  203. * 功能描述: 读socket
  204. * 输入参数:
  205. * 输出参数:
  206. * 返 回:
  207. * 流程描述:
  208. * 说明:
  209. * 修改记录:
  210. * [修改人] [日期] - [描述]
  211. ***********************************************************/
  212. int read_socket(int socket_id, char *pbuf, int len){
  213.     int num;
  214.     int i;
  215.     
  216.     if(len <= 0) {
  217.         return     read(socket_id, pbuf, sizeof(pbuf));
  218.     }

  219.     i = 0;
  220.     do{
  221.         num = read(socket_id, &(pbuf[i]), len - i);
  222.         if (num <= 0){
  223.             /* LOG: Read socket error exit. */
  224.             return(-1);
  225.         }
  226.         i += num;
  227.     } while (i < len);

  228.     return(i);
  229. }

  230. /***********************************************************
  231. * 函 数 名:write_socket
  232. * 功能描述: 写socket
  233. * 输入参数:
  234. * 输出参数:
  235. * 返 回:
  236. * 流程描述:
  237. * 说明:
  238. * 修改记录:
  239. * [修改人] [日期] - [描述]
  240. ***********************************************************/
  241. int write_socket(int socket_id, char *pbuf, int len){
  242.     int num;
  243.     int i;

  244.     if (len <= 0) return(0);
  245.         
  246.     i = 0;
  247.     do{
  248.         num = write(socket_id, &(pbuf[i]), len - i);
  249.         if (num < 0){
  250.             /* LOG: Write socket error exit. */
  251.             return(-1);
  252.         }
  253.         i += num;
  254.     } while (i < len);
  255.     
  256.     return(i);
  257. }

阅读(814) | 评论(0) | 转发(0) |
0

上一篇:共享内存

下一篇:socket服务端

给主人留下些什么吧!~~