• Linux_socket一些基本函数和结构体


     1 /* timeserv.c  a socket -based time of day server 访问显示时间
     2  */
     3 #include <stdio.h>
     4 #include <unistd.h>
     5 #include <sys/types.h>
     6 #include <sys/socket.h>
     7 #include <netinet/in.h>
     8 #include <netdb.h>
     9 #include <time.h>
    10 #include <strings.h>
    11 
    12 #define PORTNUM 13000 //端口
    13 #define HOSTLEN 256
    14 #define oops(msg) {perror(msg); exit(1);}
    15 
    16 int main(int argc ,char* argv[]) {
    17   struct sockaddr_in saddr; 
    18   /*****************************************************************************
    19    * strcut sockaddr 在socket domain 为 AF_INET domain,时 socketaddr结构定义为:
    20    * struct sockadr_in{
    21    *   unsigned short int sin_family; //代指协议族,在socket编程中只能为AF_INET.为调用socket()时的domain参数,即AF_XXXX的值
    22    *   uint16_t sin_port;  //为使用的port编号
    23    *   struct in_addr sin_addr;   //sin_addr.s_addr为IP地址
    24    *   unsigned char sin_zero[8]; //未使用
    25    * }
    26    *****************************************************************************/
    27   struct hostent * hp;
    28   /*****************************************************************************
    29    * strcut hostent {
    30    *   char *h_name;  //主机的规范名,eg:www.google.com的规范名其实是www.I.google.com
    31    *   char **h_aliases; //主机别名,eg:www.google.com就是google的别名,也许有很多别名
    32    *   int h_addrtype;   //表示主机ip类型,ipv4(AF_INET) , ipv6(AF_INET6) 
    33    *   int h_length;     //表示主机ip长度
    34    *   char **h_addr_list;  //表示主机ip地址,注意这个是以网络字节序存储的,需要打印用inet_ntop()函数;并且 h_addr为h_addr_list的第一地址
    35      }
    36    *****************************************************************************/
    37   char hostname[HOSTLEN];   //address
    38   int sock_id, sock_fd;     //line id, file desc
    39   FILE *sock_fp;            //use socket as stream
    40   char * ctime();           //convert secs to string
    41   time_t thetime;           //the time we report
    42   /*** Step1: ask kernel for a socket***/
    43   sock_id = socket(PF_INET, SOCK_STREAM, 0);   //get a socket
    44   /*sockid = socket(int domain, int type, int protocol)
    45    *domain 通信域:PF_INET用于Internet socket; type类型:socket的类型,SOCK_STREAM类似管道; protocol 协议: 所用协议,默认为0*/
    46   if(sock_id==-1)
    47     oops("socket");
    48   
    49   /*** Step2: bind address to socket, Address is host ,port ***/
    50   bzero((void*)&saddr, sizeof(saddr));
    51   gethostname(hostname, HOSTLEN);  //获取主机名
    52   hp=gethostbyname(hostname);      //获取主机信息 get info about host
    53 
    54   bcopy((void*)hp->h_addr, (void*)&saddr.sin_addr, hp->h_length);//复制ip到saddr中
    55   saddr.sin_port=htons(PORTNUM); //填入端口 fill in socket port
    56   /*其中htons函数,是进行htons转换,改变大端设置为小端结构*/
    57   saddr.sin_family=AF_INET;     //填入协议族
    58   
    59   if(bind(sock_id, (struct sockaddr*)&saddr, sizeof(saddr)) !=0 ) //绑定ip地址端口号到socket上
    60     oops("bind");
    61   
    62   /*** Step3: allow incoming calls with Qsize=1 on socket***/
    63   if(listen(sock_id, 1)!=0)
    64     /****************************************************************************
    65      listen请求内核允许指定的socket接收接入呼叫,监听socket上的连接,并不是所用类型的socket都能接收接入呼叫,但SOCK_STREAM类型是可以的。第二个参数指出接收队列的长度
    66     ****************************************************************************/
    67     oops("listen");
    68   
    69   /*
    70    * main loop: accept(), write(), close()
    71    */
    72   while(1) {
    73     sock_fd = accept(sock_id, NULL, NULL); //wait for call
    74     printf("Wow! got a call!
    ");
    75     if(sock_fd == -1)
    76       oops("accept");
    77     
    78     sock_fp = fdopen(sock_fd, "w"); //we'll write to the
    79     if(sock_fp == NULL)             //socket as a stream 
    80       oops("fdopen");
    81     thetime = time(NULL);
    82     
    83     fprintf(sock_fp, "The time here is ...");
    84     fprintf(sock_fp, "%s", ctime(&thetime));
    85     fclose(sock_fp);
    86   }
    87   return 0;
    88 }

    运行操作方法:

    1.gcc timeserv.c -o timeserv

    2. ./timeserv&   启动服务以"&"符号结尾,所以shell将运行它但不调用wait调用。

    3.可以用telnet连接此服务器上:

      telnet 'hostname' 13000 (hostname 可以用echo $HOSTNAME 来查看)

  • 相关阅读:
    SpringMVC + Spring + MyBatis 学习笔记:遭遇order by 排序问题
    SpringMVC + Spring + MyBatis 学习笔记:SpringMVC和Spring一同工作的时候,AOP事务管理不起作用的解决方法
    SpringMVC + Spring + MyBatis 学习笔记:提交数据遭遇基础类型和日期类型报400错误解决方法
    SpringMVC + Spring + MyBatis 学习笔记:为MyBatis增加打印SQL功能 (最简化配置)
    [转]大部分人努力程度之低,根本轮不到拼天赋
    String内存陷阱简介
    同为程序员 为什么我的工资最低
    在程序员的眼里,用户是这样使用他们开发的软件的
    POI怎么和项目结合起来使用
    uploadify
  • 原文地址:https://www.cnblogs.com/wizzhangquan/p/4083713.html
Copyright © 2020-2023  润新知