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!\n");
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 来查看)

时间: 2024-11-02 23:36:08

Linux_socket一些基本函数和结构体的相关文章

关于结构体

1.结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,叫做结构. typedef struct People { int a; char b; double c; }P: 其中:struct是关键词, People是标签, a b c是成员, P是此结构体声明的变量. 于是在声明变量的时候就可:P p1; 这里的P实际上就是struct People的别名.P==struct People 另外这里也可以不写People(于是也不能struct People p1;了,

Linux C中结构体初始化

    在阅读GNU/Linux内核代码时,我们会遇到一种特殊的结构初始化方式.该方式是某些C教材(如谭二版.K&R二版)中没有介绍过的.这种方式称为指定初始化(designated initializer).下面我们看一个例子,Linux-2.6.x/drivers/usb/storage/usb.c中有这样一个结构体初始化项目: static struct usb_driver usb_storage_driver = { .owner = THIS_MODULE, .name = "

在Swift结构体中如何实现写时复制?

结构体(Struct)在Swift语言中占有重要地位,在Swift标准库中,大约有90%的公开类型都是结构体,包括我们常用的Array.String.Dictionary.结构体相比类,一个最重要的特性就是它是值类型,而类似引用类型.值类型是通过复制值来赋值的,而不是引用同一个内存地址,这样就不存在数据共享的问题,能防止意外的数据改变,并且它是线程安全的. 举一个很简单的例子,在objc中,数组是类,是引用类型,在Swift中,数组是结构体,是值类型.因此下面的代码中: let array1 =

结构体的大小

系统在存储结构体变量时存在地址对齐问题,编译器在编译程序时会遵循两条原则: 一.结构体变量中成员的偏移量必须是成员大小的整数倍: 二.结构体大小必须是所有成员大小的整数倍. 1 #include<stdio.h> 2 3 struct a{ 4 int i; 5 float f; 6 char c; 7 double d; 8 long l; 9 }b; 10 11 int main(){ 12 printf("%d\n",sizeof(b.i));// 4 13 prin

关于OC中直接打印结构体,点(CGRect,CGSize,CGPoint,UIOffset)等数据类型

关于OC直接打印结构体,点(CGRect,CGSize,CGPoint,UIOffset)等数据类型,我们完全可以把其转换为OC对象来进项打印调试,而不必对结构体中的成员变量进行打印.就好比我们可以使用NSStringFromCGRect(CGRect rect)来直接打印一个结构体,其他打印可以参考以下内容 UIKIT_EXTERN NSString *NSStringFromCGPoint(CGPoint point); UIKIT_EXTERN NSString *NSStringFrom

38-oc常用结构体

常用结构体 在开发中苹果推荐我们使用CG开头的结构体, 也就是说NS开头的结构体一般不用 OC中定义一个点,用什么结构体 NSPoint; CGPoint point = NSMakePoint(10, 20); OC中保存物体尺寸的,用什么结构体 NSSize; CGSize size = NSMakeSize(100, 50); OC中保存某个物体的位置和尺寸,用什么结构体 NSRect; CGRect rect = NSMakeRect(10, 20, 100, 50); NSNumber

结构体在固件库中的应用

上次介绍了一般结构体的定义以及引用方法,那么接下来将对结构体在官方固件库是如何具体使用的做出简单说明. 结构体指针成员变量引用方法是通过“→”符号来实现,比如要访问student1结构体指针指向的结构体的成员变量name,那么方法是: stuednt1—>name; 如在STM32官方固件库中对端口使用模式结构体定义如下: typedef enum { GPIO_Mode_AIN = 0x0, //模拟输入模式 GPIO_Mode_IN_FLOATING = 0x04, //浮空输入模式 GPI

C# 定义一个学生的结构体,输入学生信息,学号,姓名,身高,按身高排序输出

class Program { //定义一个结构体 struct student//student就是我们自己造的新数据类型 { public int code;//public修饰符 public string name;//结构体的成员 public decimal height; } static void Main(string[] args) { ArrayList arr = new ArrayList(); for (int i = 0; i < 3; i++) { student

类和结构体

//类  class A {     var a = 0 } let classA = A() classA.a = 12     //虽然classA定义为常量,但是仍然可以修改A类中的变量值;结构体则不可以 //类属于引用类型,结构体属于值类型