首页 > 代码库 > Linux_socket一些基本函数和结构体

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 25614 #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.com31    *   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];   //address38   int sock_id, sock_fd;     //line id, file desc39   FILE *sock_fp;            //use socket as stream40   char * ctime();           //convert secs to string41   time_t thetime;           //the time we report42   /*** Step1: ask kernel for a socket***/43   sock_id = socket(PF_INET, SOCK_STREAM, 0);   //get a socket44   /*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 host53 54   bcopy((void*)hp->h_addr, (void*)&saddr.sin_addr, hp->h_length);//复制ip到saddr中55   saddr.sin_port=htons(PORTNUM); //填入端口 fill in socket port56   /*其中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 call74     printf("Wow! got a call!\n");75     if(sock_fd == -1)76       oops("accept");77     78     sock_fp = fdopen(sock_fd, "w"); //we‘ll write to the79     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 来查看)

Linux_socket一些基本函数和结构体