中国IT职业教育领先品牌
精品课程 全程面授
学习Linux编程哪个好
想知道Linux编程培训哪家好?先来了解一下什么是Linux编程吧! Linux下的网络编程指的是socket套接字编程,入门比较简单。在学校里学过一些皮毛,平时就是自学玩,没有见识过真正的socket编程大程序,比较遗憾。总感觉每次看的时候都有收获,但是每次看完了之后,过段时间不看,重新拾起这些知识的时候又要从头开始,所以,在这里做个笔记也算是做个模板,以后可以直接从某一个阶段开始接着玩……
IO复用之select函数
select函数用于IO复用,它用于监视多个文件描述符集合,看规定时间内有没有事件产生。
int select(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout); 功能介绍:
该函数主要的功能是对需要操作的文件描述符集合进行查询,目标文件描述符中有可以读,写或者异常错误操作的情况时,会返回一个大于0的整数值,表示可以对该文件描述符进行操作。select函数返回0,表示超时;返回-1,表示发生错误;返回大于0的整数值,表示有符合要求的文件描述事件产生。当不需要监视某种文件描述符时,设置参数为NULL。 参数说明:
nfds:是一个整型变量,其值是加入到后面三个文件描述符集合中的最大文件描
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
述符的值加1。
readfds:可读文件描述符集合,通过FD_SET向该文件描述符集合中加入需要监视的目标文件描述符,当有符合要求的文件描述符时,select会返回一个大于0的值,同时会把原来集合中的不可读的文件描述符清掉,如果想在次监视可读文件描述,需要重新FD_SET。
writefds:可写文件描述符集合,同样通过FD_SET函数向结合中加入需要被监视的目标文件描述符,select返回时,同样会把不可写文件描述符清掉,如果需要重新监视文件描述符,需要重新FD_SET设置。
exceptfds:该描述符集合是用于监视文件描述符集合中的任何文件是否发生错误。
timeout:用于设置超时的最长等待时间,如果在该规定时间内没有返回一个大于0的值,则返回0,表示超时。如果超时间设置为NULL,表示阻塞等待,直到符合条件的文件描述符在集合中出现,当timeout的值为0时,select会立即返回。
timeout的数据结构如下: struct timeval {
time_t tv_sec;
/*秒*/
long tv_usec;
/*微秒*/ }; 有4个宏可以操作文件描述符集合:
FD_ZERO: 用于清空文件描述符集合,FD_ZERO(&fds)。
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
FD_SET:向某个文件描述符结合中加入文件描述符, FD_SET(fd, &fds)。 FD_CLR:从某个文件描述符结合中取出某个文件描述符, FD_CLR(fd, &fds)。 FD_ISSET:测试某个文件描述符是否在某个文件描述符集合中, FD_ISSET(fd, &fds)。
下面是本实用socket编程,并且利用select IO实现的一个server和client实时通信的例子,为了显示更直观,加了一些打印以及接收数据上的操作,程序还有bug,希望阅读的人不要介意,或者自行修改。代码如下,可以作为学习socket和select的一个实例。 server.c文件源码如下:
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7
8 #define SPORT 8888
9 #define BACKLOG 5 10 #define SIZE 100 11
12 int main(void) 13 {
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
int sockfd, clientfd;
struct sockaddr_in sockServer, sockClient; 16
struct timeval tv; 17
fd_set readfds, writefds; 18
int readlen, writelen; 19
char buffer[SIZE]; 20
21
sockfd = socket(AF_INET, SOCK_STREAM, 0); 22
if(sockfd
{ 24
perror(\"create socket failed!\\n\"); 25
return -1; 26
} 27
28
bzero(&sockServer, 0); 29
sockServer.sin_family = AF_INET; 30
sockServer.sin_port = htons(SPORT); 31
sockServer.sin_addr.s_addr = htonl(INADDR_ANY); 32
33
if(bind(sockfd, (struct sockaddr *)&sockServer, sizeof(struct sockaddr_in))
{
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
35
perror(\"bind socket failed!\\n\"); 36
return -1; 37
} 38
39
if(listen(sockfd, BACKLOG)
{ 41
perror(\"listen failed!\\n\"); 42
} 43
44
printf(\"Server is listening ......\\n\"); 45
46
while(1) 47
{ 48
int len = sizeof(struct sockaddr_in); 49
int ret; 50
time_t timet; 51
52
clientfd = accept(sockfd, (struct sockaddr *)&sockClient, &len); 53
if(clientfd
{ 55
perror(\"accept failed!\\n\");
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
56
return -1; 57
} 58
59
for(;;) 60
{ 61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
FD_ZERO(&readfds); FD_SET(1, &readfds); FD_SET(clientfd, &readfds); tv.tv_usec = 0; tv.tv_sec = 60;
ret = select(clientfd+1, &readfds, NULL, NULL, &tv); switch(ret) {
case 0:
printf(\"select timeout!\\n\");
break;
case -1:
perror(\"select return failed!\\n\");
goto closesocket;
default:
if(FD_ISSET(clientfd, &readfds) > 0)
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
78
{ 79
memset(buffer, 0, SIZE); 80
readlen = read(clientfd, buffer, SIZE); 81
if(readlen
{ 83
84
85
86
87
ctime(&timet)); 88
89
90
91
92
93
94
95
96
97
98
perror(\"read data failed!\\n\");
goto closesocket;
}
time(&timet);
printf(\"Opposite: %d %s\", clientfd,
strcat(buffer, \"\\n\");
writelen = write(0, buffer, readlen+1);
if(writelen
{
perror(\"write data failed!\\n\");
goto closesocket;
} }
if(FD_ISSET(1, &readfds) > 0) {
time(&timet);
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
99
printf(\"Owner: %d %s\\n\", sockfd, ctime(&timet)); 100
memset(buffer, 0, SIZE); 101
readlen = read(1, buffer, SIZE); 102
if(readlen
104
105
106
107
108
109
110
111
112
113
} 114
} 115
} 116 closesocket: 117
close(clientfd); 118
} 119
close(sockfd);
{
perror(\"read data failed!\\n\");
goto closesocket; }
writelen = write(clientfd, buffer, readlen); if(writelen
perror(\"write data failed!\\n\");
goto closesocket; } 千锋教育www.daodoc.com
中国IT职业教育领先品牌
120
121
return 0; 122 }
client.c文件源码如下:
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7
8 #define SPORT 8888
9 #define SIZE 100 10
11 int main(void) 12 { 13
int sockfd, clientfd;
struct sockaddr_in sockServer; 15
struct timeval tv; 16
fd_set readfds; 17
int readlen, writelen;
精品课程 全程面授
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
char buffer[SIZE]; 19
time_t timet; 20
21
sockfd = socket(AF_INET, SOCK_STREAM, 0); 22
if(sockfd
{ 24
perror(\"create socket failed!\\n\"); 25
return -1; 26
} 27
28
bzero(&sockServer, 0); 29
sockServer.sin_family = AF_INET; 30
sockServer.sin_port = htons(SPORT); 31
sockServer.sin_addr.s_addr = htonl(INADDR_ANY); 32
33
if(connect(sockfd, (struct sockaddr *)&sockServer, sizeof(struct sockaddr_in))
{ 35
perror(\"connect failed!\\n\"); 36
close(sockfd); 37
}
38
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
39
while(1) 40
{ 41
int ret; 42
43
FD_ZERO(&readfds); 44
FD_SET(1, &readfds); 45
FD_SET(sockfd, &readfds); 46
tv.tv_usec = 0; 47
tv.tv_sec = 60; 48
49
ret = select(sockfd+1, &readfds, NULL, NULL, &tv); 50
switch(ret) 51
{ 52
case 0: 53
printf(\"select timeout!\\n\"); 54
break; 55
case -1: 56
perror(\"select return failed!\\n\"); 57
goto closesocket; 58
default: 59
if(FD_ISSET(sockfd, &readfds) > 0) 60
{
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
61
memset(buffer, 0, SIZE); 62
readlen = read(sockfd, buffer, SIZE); 63
if(readlen
{ 65
perror(\"read data failed!\\n\"); 66
67
68
69
ctime(&timet)); 70
71
72
73
74
75
76
77
78
79
80
81
goto closesocket;
}
time(&timet);
printf(\"Opposite: %s %s\", \"Server\",
strcat(buffer, \"\\n\");
writelen = write(0, buffer, readlen + 1);
if(writelen
{
perror(\"write data failed!\\n\");
goto closesocket;
} }
if(FD_ISSET(1, &readfds) > 0) {
time(&timet);
printf(\"Owner: %d %s\\n\", sockfd,
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
ctime(&timet)); 82
memset(buffer, 0, SIZE); 83
readlen = read(1, buffer, SIZE); 84
if(readlen
{ 86
perror(\"read data failed!\\n\"); 87
goto closesocket; 88
} 89
writelen = write(sockfd, buffer, readlen); 90
if(writelen
{ 92
perror(\"write data failed!\\n\"); 93
goto closesocket; 94
} 95
} 96
} 97
98 closesocket: 99
close(clientfd); 100
} 101
close(sockfd); 102
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
103
return 0; 104 }
运行结果如下所示:
以上就是千锋Linux学院的学习笔记。 另附心得体会一篇:
从零基础开始学Linux或者是转行学习Linux,参加培训会保证你在单位时间内学到更多,毕竟随着Linux行业的快速发展,未来必将会面临更多的竞争,所以只有不遗余力的把自己打造成一把利剑,从专业度到职业素质,只有比别人更突出和优秀,才能够在这个相互选择的世界当中拥有更多的选择权利。现在想要学习Linux技术,只有通过参加培训才可以保证快速掌握所学知识和技能,所以培训是比较靠谱的。
学习Linux编程哪个好?千锋教育的Linux课程专注于当前热门的Linux相关技术,就Linux而言,内容全面而细致的。Linux教学团队由众多名师打造,拥有多年教学经验和高超的Linux授课技巧和实战视野,让你理论和实战兼得。
千锋教育www.daodoc.com
中国IT职业教育领先品牌
精品课程 全程面授
千锋教育www.daodoc.com