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

全部博文(573)

文章存档

2018年(3)

2016年(48)

2015年(522)

分类: LINUX

2015-12-02 15:32:22


点击(此处)折叠或打开

  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. #include <netdb.h>

  20. #define SER_IP "127.0.0.1" /*服务器的IP地址*/

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

  23. int main(int argc, char ** argv) /*服务端程序*/
  24. {
  25.     pid_t pid;
  26.     char ip_buf[32];
  27.     char readbuf[1024];
  28.     int sockfd = -1; /*监听套接字*/
  29.     int newfd = -1; /*连接套接字*/
  30.     int ret = -1;
  31.     int opt = 1;
  32.     int len;
  33.     int i=0;
  34.     int read_count = 1; /*读取次数*/
  35.     struct sockaddr_in seraddr; /*用来保存服务器自己的ip地址和端口号的*/
  36.     struct sockaddr_in cliaddr; /*用来保存连接过来的客户的ip地址和端口号的*/
  37.     struct sockaddr_in bindaddr; /*用来保存连接过来的客户的ip地址和端口号的*/
  38.     struct sockaddr lbindaddr;
  39.     
  40.     memset(ip_buf, 0, sizeof(ip_buf));
  41.     memset(readbuf, 0, sizeof(readbuf));
  42.     
  43.     memset(&seraddr, 0, sizeof(seraddr));
  44.     memset(&cliaddr, 0, sizeof(cliaddr));
  45.     memset(&bindaddr, 0, sizeof(bindaddr));
  46.     memset(&lbindaddr, 0, sizeof(lbindaddr));
  47.     
  48.     sockfd = socket(AF_INET, SOCK_STREAM, 0); /*创建连接套接字,TCP协议*/
  49.     if(sockfd < 0)
  50.     {
  51.         return -1;
  52.     }
  53.     setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); /*将服务端设置具有端口号可以重复*/

  54.     seraddr.sin_family = AF_INET; /*指定服务器地址协议族*/
  55.     seraddr.sin_port = htons(4989);     /*指定要监听的服务器的端口号*/
  56.     /*seraddr.sin_addr.s_addr = INADDR_ANY;*/ /*指定要监听的服务器的ip:0.0.0.0:则客户端可连 127.0.0.1 和 真实的主机地址*/
  57.     
  58.     char * hostname = NULL;
  59.     hostname = getenv("HOST");
  60.     if(hostname == NULL)
  61.     {
  62.         printf("HOST环境变量不存在!\n");
  63.         exit(-1);
  64.     }
  65.     struct hostent * myhost;
  66.     myhost = gethostbyname(hostname);
  67.     if(myhost == NULL)
  68.     {
  69.         printf("myhost is null!\n");
  70.         exit(-1);
  71.     }
  72.     bcopy(myhost->h_addr, &seraddr.sin_addr, myhost->h_length);
  73.     char ipbuf[128];
  74.     memset(ipbuf, 0, sizeof(ipbuf));
  75.     inet_ntop(AF_INET, &seraddr.sin_addr.s_addr, ipbuf, sizeof(ipbuf));
  76.     printf("主机名=[%s],IP地址=[%s]\n", myhost->h_name, ipbuf);
  77.     printf("IP地址=[%s]\n", ipbuf);

  78.     ret = bind(sockfd, (struct sockaddr*)&seraddr, sizeof(struct sockaddr)); /*将IP地址,端口号和文件绑定,为套接字命名*/
  79.     if(ret < 0)
  80.     {
  81.         printf("bind err! ret = [%d]\n", ret);
  82.         return -1;
  83.     }
  84.     
  85.     ret = listen(sockfd, 10); /*监听*/
  86.     if(ret < 0)
  87.     {
  88.         return -1;
  89.     }
  90.     
  91.     while(1)
  92.   {
  93.           printf("等待客户端连接.....\n");
  94.             len = sizeof(cliaddr); /*-结果参数*/
  95.             /*if((newfd=accept(sockfd,(struct sockaddr *)&cliaddr,(socklen_t *)&len))==-1)*/
  96.             if((newfd=accept(sockfd, (struct sockaddr *)NULL, (socklen_t *)NULL)) == -1) /*不关心客户端标识*/
  97.       {
  98.           perror("accept() failed");
  99.           exit(1);
  100.       }
  101.       if((pid=fork())>0)
  102.       {
  103.           close(newfd);
  104.           continue;
  105.       }
  106.       else if(pid==0)
  107.       {
  108.           close(sockfd);
  109.           /*
  110.           memset(ip_buf, 0, sizeof(ip_buf));
  111.                     inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, ip_buf, sizeof(ip_buf));
  112.                     printf("客户IP=[%s]\n", ip_buf);
  113.                     printf("客户PORT=[%d]\n", ntohs(cliaddr.sin_port));
  114.                     */
  115.                     
  116.                     char    serv_ip[20];
  117.                     char    guest_ip[20];
  118.                  struct sockaddr_in serv;
  119.                  struct sockaddr_in guest;
  120.                  socklen_t serv_len = sizeof(serv);
  121.                  socklen_t guest_len = sizeof(guest);
  122.                 
  123.                  getsockname(newfd, (struct sockaddr *)&serv, &guest_len);
  124.                  getpeername(newfd, (struct sockaddr *)&guest, &serv_len);
  125.                 
  126.                  inet_ntop(AF_INET, &guest.sin_addr.s_addr, guest_ip, sizeof(guest_ip));
  127.                  inet_ntop(AF_INET, &serv.sin_addr.s_addr, serv_ip, sizeof(serv_ip));
  128.                  printf("服务端IP和PORT[%s]:[%d]\n", serv_ip, ntohs(serv.sin_port));
  129.                  printf("客户端IP和PORT[%s]:[%d]\n", guest_ip, ntohs(guest.sin_port));
  130.                     
  131.                     /*ret = write(newfd, "OK", sizeof("OK"));*/ /*告诉客户端,服务器OK了*/
  132.                     while(1)
  133.                     {
  134.                             printf("服务器写入套接字的内容:\n");
  135.                             memset(readbuf, 0, sizeof(readbuf));
  136.                             ret = read(STDIN_FILENO, readbuf, sizeof(readbuf));
  137.                             printf("read=[%s] ret = [%d]\n", readbuf, ret);
  138.                             
  139.                             ret = write(newfd, readbuf, strlen(readbuf));
  140.                             printf("write=[%s] ret = [%d]\n", readbuf, ret);
  141.                     }

  142.                     close(newfd);
  143.           exit(0);
  144.       }
  145.       else
  146.       {
  147.           printf("fork() failed");
  148.           exit(0);
  149.       }
  150.   }
  151.   close(sockfd);

  152.     return 0;
  153. }


  154. /*确保读取指定长度的字符*/
  155. ssize_t readn(int fd, void * ptr, size_t n)
  156. {
  157.         size_t nleft;
  158.         ssize_t nread;
  159.         
  160.         nleft = n;
  161.         while(nleft > 0)
  162.         {
  163.                 if((nread = read(fd, ptr, nleft)) < 0)
  164.                 {
  165.                         if(nleft == n)
  166.                                 return -1;
  167.                         else
  168.                                 break;
  169.                 }
  170.                 else if(nread == 0)
  171.                 {
  172.                         break;
  173.                 }
  174.                 nleft -= nread;
  175.                 ptr += nread;
  176.         }
  177.         return(n - nleft);
  178. }


  179. /*确保写入指定长度的字符*/
  180. ssize_t writen(int fd, sonst void * ptr, size_t n)
  181. {
  182.         size_t nleft;
  183.         ssize_t nwrte;
  184.         
  185.         nleft = n;
  186.         while(nleft > 0)
  187.         {
  188.                 if((nwrte = write(fd, ptr, nleft)) < 0)
  189.                 {
  190.                         if(nleft == n)
  191.                                 return -1;
  192.                         else
  193.                                 break;
  194.                 }
  195.                 else if(nwrte == 0)
  196.                 {
  197.                         break;
  198.                 }
  199.                 nleft -= nwrte;
  200.                 ptr += nwrte;
  201.         }
  202.         return(n - nleft);
  203. }


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

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

  231.     return(i);
  232. }

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

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

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

上一篇:socket客户端

下一篇:epoll函数

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