linux如何实现网络高级编程,嵌入式Linux网络编程之:网络高级编程-嵌入式系统-与非网...

10.3  网络高级编程

在实际情况中,人们往往遇到多个客户端连接服务器端的情况。由于之前介绍的如connet()、recv()和send()等都是阻塞性函数,如果资源没有准备好,则调用该函数的进程将进入睡眠状态,这样就无法处理I/O多路复用的情况了。本节给出了两种解决I/O多路复用的解决方法,这两个函数都是之前学过的fcntl()和select()(请读者先复习第6章中的相关内容)。可以看到,由于在Linux中把socket也作为一种特殊文件描述符,这给用户的处理带来了很大的方便。

1.fcntl()

函数fcntl()针对socket编程提供了如下的编程特性。

n 非阻塞I/O:可将cmd设置为F_SETFL,将lock设置为O_NONBLOCK。

n 异步I/O:可将cmd设置为F_SETFL,将lock设置为O_ASYNC。

下面是用fcntl()将套接字设置为非阻塞I/O的实例代码:

/* net_fcntl.c */

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define PORT                  1234

#define MAX_QUE_CONN_NM        5

#define BUFFER_SIZE             1024

int main()

{

struct sockaddr_in server_sockaddr, client_sockaddr;

int sin_size, recvbytes, flags;

int sockfd, client_fd;

char buf[BUFFER_SIZE];

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

perror("socket");

exit(1);

}

server_sockaddr.sin_family = AF_INET;

server_sockaddr.sin_port = htons(PORT);

server_sockaddr.sin_addr.s_addr = INADDR_ANY;

bzero(&(server_sockaddr.sin_zero), 8);

int i = 1;/* 允许重复使用本地地址与套接字进行绑定 */

setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));

if (bind(sockfd, (struct sockaddr *)&server_sockaddr,

sizeof(struct sockaddr)) == -1)

{

perror("bind");

exit(1);

}

if(listen(sockfd,MAX_QUE_CONN_NM) == -1)

{

perror("listen");

exit(1);

}

printf("Listening....\n");

/* 调用fcntl()函数给套接字设置非阻塞属性 */

flags = fcntl(sockfd, F_GETFL);

if (flags 

{

perror("fcntl");

exit(1);

}

while(1)

{

sin_size = sizeof(struct sockaddr_in);

if ((client_fd = accept(sockfd,

(struct sockaddr*)&client_sockaddr, &sin_size)) 

{

perror("accept");

exit(1);

}

if ((recvbytes = recv(client_fd, buf, BUFFER_SIZE, 0)) 

{

perror("recv");

exit(1);

}

printf("Received a message: %s\n", buf);

} /*while*/

close(client_fd);

exit(1);

}

运行该程序,结果如下所示:

$ ./net_fcntl

Listening....

accept: Resource temporarily unavailable

可以看到,当accept()的资源不可用(没有任何未处理的等待连接的请求)时,程序就会自动返回。

2.select()

使用fcntl()函数虽然可以实现非阻塞I/O或信号驱动I/O,但在实际使用时往往会对资源是否准备完毕进行循环测试,这样就大大增加了不必要的CPU资源的占用。在这里可以使用select()函数来解决这个问题,同时,使用select()函数还可以设置等待的时间,可以说功能更加强大。下面是使用select()函数的服务器端源代码。客户端程序基本上与10.2.3小节中的例子相同,仅加入一行sleep()函数,使得客户端进程等待几秒钟才结束。

/* net_select.c */

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#define PORT                 4321

#define MAX_QUE_CONN_NM       5

#define MAX_SOCK_FD            FD_SETSIZE

#define BUFFER_SIZE            1024

int main()

{

struct sockaddr_in server_sockaddr, client_sockaddr;

int sin_size, count;

fd_set inset, tmp_inset;

int sockfd, client_fd, fd;

char buf[BUFFER_SIZE];

if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

perror("socket");

exit(1);

}

server_sockaddr.sin_family = AF_INET;

server_sockaddr.sin_port = htons(PORT);

server_sockaddr.sin_addr.s_addr = INADDR_ANY;

bzero(&(server_sockaddr.sin_zero), 8);

int i = 1;/* 允许重复使用本地地址与套接字进行绑定 */

setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));

if (bind(sockfd, (struct sockaddr *)&server_sockaddr,

sizeof(struct sockaddr)) == -1)

{

perror("bind");

exit(1);

}

if(listen(sockfd, MAX_QUE_CONN_NM) == -1)

{

perror("listen");

exit(1);

}

printf("listening....\n");

/*将调用socket()函数的描述符作为文件描述符*/

FD_ZERO(&inset);

FD_SET(sockfd, &inset);

while(1)

{

tmp_inset = inset;

sin_size=sizeof(struct sockaddr_in);

memset(buf, 0, sizeof(buf));

/*调用select()函数*/

if (!(select(MAX_SOCK_FD, &tmp_inset, NULL, NULL, NULL) > 0))

{

perror("select");

}

for (fd = 0; fd 

{

if (FD_ISSET(fd, &tmp_inset) > 0)

{

if (fd == sockfd)

{ /* 服务端接收客户端的连接请求 */

if ((client_fd = accept(sockfd,

(struct sockaddr *)&client_sockaddr, &sin_size))== -1)

{

perror("accept");

exit(1);

}

FD_SET(client_fd, &inset);

printf("New connection from %d(socket)\n", client_fd);

}

else /* 处理从客户端发来的消息 */

{

if ((count = recv(client_fd, buf, BUFFER_SIZE, 0)) > 0)

{

printf("Received a message from %d: %s\n",

client_fd, buf);

}

else

{

close(fd);

FD_CLR(fd, &inset);

printf("Client %d(socket) has left\n", fd);

}

}

} /* end of if FD_ISSET*/

} /* end of for fd*/

} /* end if while while*/

close(sockfd);

exit(0);

}

运行该程序时,可以先启动服务器端,再反复运行客户端程序(这里启动两个客户端进程)即可,服务器端运行结果如下所示:

$ ./server

listening....

New connection from 4(socket)                 /* 接受第一个客户端的连接请求*/

Received a message from 4: Hello,First!    /* 接收第一个客户端发送的数据*/

New connection from 5(socket)              /* 接受第二个客户端的连接请求*/

Received a message from 5: Hello,Second!   /* 接收第二个客户端发送的数据*/

Client 4(socket) has left                   /* 检测到第一个客户端离线了*/

Client 5(socket) has left                   /* 检测到第二个客户端离线了*/

$ ./client localhost Hello,First! & ./client localhost Hello,Second

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305690.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET斗鱼直播弹幕客户端(2021)

.NET斗鱼直播弹幕客户端(2021)离之前更新的两篇《.NET斗鱼直播弹幕客户端》已经有一段时间,近期有许多客户向我反馈刚好有这方面的需求,但之前的代码不能用了——但网上许多流传的Node.js、Python脚本却可以用,这岂能忍?&#xff…

McAfee推免费版SiteAdvisor安全上网工具

McAfee近期宣布推出完全免费版McAfee SiteAdvisor上网工具。McAfee SiteAdvisor是业界第一款Web安全工具,能够主动地提醒用户在浏览、搜索和即时通信或收发电子邮件时所遇到的危险站点,避免遭到网络钓鱼、间谍软件等恶意程序的***。 McAfee SiteAdvisor是…

9050 端口 linux 进程,windows和linux查看端口占用情况

一、Windows平台在windows命令行窗口下执行:1.查看所有的端口占用情况C:\>netstat -ano协议 本地地址 外部地址 状态 PIDTCP 127.0.0.1:1434 0.0.0.0:0 LISTENING 3236TC…

Exceptionless服务端本地化部署

背景分布式异常日志收集框架Exceptionless是开源的工具,根据官方给出的说明:Exceptionless提供两种使用方式,一种是官网创建账号,需要付费,免费版有限制;一种是自己搭建本地项目,无任何限制。准备安装包准备…

微软所谓的无人工介入的自动的机器翻译系统

近日在微软网站上查找资料,发现一个资料里有如下的声明性描述:注意:这篇文章是由无人工介入的自动的机器翻译系统翻译完成。这些文章是微软为不懂英语的用户提供的, 以使他们能够理解这些文章的内容。微软不保证机器翻译的正确度,也不对由于内容的误译或…

ABP vnext模块化架构的最佳实践的实现

在上一篇文章《手把手教你用Abp vnext构建API接口服务》中,我们用ABP vnext实现了WebAPI接口服务,但是并非ABP模块化架构的最佳实践。我本身也在学习ABP,我认为ABP新手应该从最佳实践开始学习,可以少走很多弯路,所以写…

WebCast学习链接

全部下载列表1. C#面向对象设计模式纵横谈系列课程 讲师:李建忠 上海祝成信息科技有限公司 高级培训讲师 MSDN特邀讲师2. ASP.NET AJAX深入浅出系列课程 讲师: 老赵 课程(1):ASP.NET AJAX 概述 课程(2):UpdatePanel的使用(…

linux删除第二次出现的字符,linux下 怎样删除文件名中包含特殊字符的文件

目录中无意间出现了 -- 这个文件[rootdev tmp]# ls-- 00 01 02 03 04 05 06 07 08 09[rootdev tmp]# lltotal 0-rw-r--r-- 1 root root 0 Oct 23 15:31 ---rw-r--r-- 1 root root 0 Oct 23 15:37 00-rw-r--r-- 1 root root 0 Oct 23 15:37 01-rw-r--r-- 1 root root 0 Oct 23 1…

全球知名跨境电商,.Net软件工程师招聘,约么?

公司:际客国际电子商务有限公司,网址:http://geekbuy.cn/工作地点:深圳市龙岗区五和大道南雅宝路1号星河WORLD B座岗位职责:中级开发工程师。薪资待遇:10K-20K,具体面议。 职位要求&#x…

被关起来日子的流水帐

2007年3月19日 老上号经过3个半小时的颠簸,在晚上7:30到达了哈尔滨,还是住在黑龙江大学旁边的学府宾馆,由于是在学校的边上,相对来说比较安全,宾馆的条件已经不如以前了,稍微显得有点陈旧&#…

krc 编辑 linux,Linux网络编程

6 berkeley - 145 -struct in_addr {unsigned long s_addr;};ina struct sockaddr_instruct in_addrina.sin_addr.s_addr 4 IP4 IP #defines6.5.21IP2h to nto Network Short Hosts H-to-n-s htons()68000n h to s l IPstolh() Short to Long Host?l htons() “Host to Networ…

iphone查看删除的短信_手机资讯:iPhone手机可以批量删除短信吗如何操作

如今使用IT数码设备的小伙伴们是越来越多了,那么IT数码设备当中是有很多知识的,这些知识很多小伙伴一般都是不知道的,就好比最近就有很多小伙伴们想要知道iPhone手机可以批量删除短信吗如何操作,那么既然现在大家对于iPhone手机可…

如何在 C# 8 中使用 模式匹配

模式匹配 是在 C# 7 中引入的一个非常????的特性,你可以在任何类型上使用 模式匹配,甚至是自定义类型,而且在 C# 8 中得到了增强,引入了大量的新模式类型,这篇文章就来讨论如何在 C# 8 中使用模式匹配。C# 8 中的表…

linux下找不到libc 库,Linux-覆盖libc open()库函数

我在库&中有glibc提供的相同的覆盖open().我首先在库中设置了LD_PRELOAD,因此当进程调用open()时,将调用库中定义的open.问题:-glibc中还有其他几个函数,一旦示例为getpt(),就会调用open(),当getpt()调用open()时,将调用glibc中定义的open(),我将如何使getpt ()…

Hadoop 中zoo_0基础如何入门HADOOP

原标题:0基础如何入门HADOOP学习一样东西,肯定先要了解这个东西是什么,那什么是HADOOP呢?我们就来看看什么是HADOOP和如何学习HADOOP及学习内容。一,什么是HADOOPHADOOP是apache旗下的一套开源软件平台HADOOP提供的功能…

.NET 5 程序高级调试-WinDbg

上周和大家分享了.NET 5开源工作流框架elsa,程序跑起来后,想看一下后台线程的执行情况。抓了个进程Dump后,使用WinDbg调试,加载SOS调试器扩展,结果无法正常使用了:0:000> .loadby sos clrUnable to find…

精妙Sql语句

1. 判断a表中有而b表中没有的记录 select a.* from tbl1 a left join tbl2 b on a.key b.key where b.key is null 虽然使用in也可以实现,但是这种方法的效率更高一些 2. 新建一个与某个表相同结构的表 select * into b from a where 1&l…

.Net在线编辑工具.NET Fiddle

介绍推荐工具:.NET Fiddle推荐理由:在线调试,编译,运行.net代码,同时支持C#,VB.NET,F#推荐说明::对于.NET开发者来说是福音,因为我们可以不用再担心环境与庞大…

Typora markdown公式换行等号对齐_下了31个markdown编辑器,我就不信选不出一个好用的...

markdown编辑器测评标准总体标准渲染领域编辑领域数据管理其他TyporaVnoteMwebJoplinZettlrmacdownulyssesMarktextghostwriterfocusedbywordmarkedFarBoxNotablebear(熊掌笔记)iA writerMarxico(马克飞象)JetBrains系列的IDEsublime(贫穷,没有插件&…

WSUS专题之二:部署与规划1

部署场景: 我们这里仅讨论和Internet完全物理隔离的企业内网的WSUS部署 Internet断开的WSUS服务器环境 部署WSUS服务时,并不要求你必须连接到Internet。对于没有连接到Internet的网络环境,你一样可以部署WSUS服务。通过在其他连接到Internet上的WSUS服务…