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 来查看)

原文地址:https://www.cnblogs.com/wizzhangquan/p/4083713.html