来源:维库电子
1 引言
随着Intenet

日益发展和普及

网络在嵌入式系统中应用非常广泛

越来越多

嵌入式设备采用Linux操作系统

Linux是

个源代码公开

免费操作系统

具有强移植性

所以对基于Linux

Socket网络编程

研究越来越重要


Socket实际是网络传输层供给应用层

编程接口

传输层则在网络层

基础上提供进程到进程问

逻辑通道

而应用层

进程则利用传输层向另

台主机

某

进程通信

Socket就是应用层和传输层的间

桥梁

如图2所示


使用Socket编程时可以开发客户机和服务器应用


它们可以在本地网络上进行通信

也可以通过Internet在全球范围内进行通信

编写并运行 Socket

客户端和服务器端


双方通过套接字建立了服务连接请求

并且通过

些思路方法提高Socket

性能

3 Socket编程
3.1 Socket类型
常见

Socket有3种类型:
(1)流式Socket(SOCK_STREAM)它提供可靠

通信流

使用面向连接

TCP协议

从而保证数据传输

正确性和顺序性:
(2)数据报Socket(SOCK_DGRAM)数据通过相互独立

报文进行传输

是无序


并且不保证可靠

无差错

它定义

种面向无连接

服务

使用数据报协议UDP;
(3)原始Socket(SOCK_RAM)它允许直接访问底层协议

功能强大但使用较为不便

主要用于

些协议

开发

本编写

Socket属于流式Socket

3.2 Socket编程流程
Socket编程采用客户/服务器模式

因此编程分为服务器端和客户端两部分

每

个Socket都用

个半相关描述(协议

本地地址

本地端口)来表示

Socket也有

个类似于文件打开



该

返回

个整型

Socket描述符

随后建立连接

数据传输等操作都通过Socket来实现

编程流程如下:服务器端首先建立Socket

返回该Socket

描述符:配置Socket

端口和IP地址;建立*甬数

检测是否有客户端向服务器发送请求

若有则接收该请求

将其放到接收队列中:从接收队列中接受

个请求;并向客户端发送确认连接信息

客户端建立

个Socket

返回该Socket

描述符;配置Socket端口和IP地址;向服务器发送连接请求

并接收服务器发回

确认连接信息

双方通信结束后

关闭其Socket

进行Socket编程

基本

有



bind


listen


accept


connect


send


recv


close


图3为Socket

编程流程图


3.3


编译和运行结果
(1)在Linux

VI编辑器下编写服务器端

serv.c和客户端

clt.c

运用交叉编译工具arm-linux-gcc,执行编译指令生成可执行文件

其指令为:
#gcc serv.c=0 serv
#gcc clt.c-0 clt
编译没有

则会生成可执行文件serv和clt

(2)配置服务器和客户端

IP

保证网络畅通

在serv.c中已将服务器

IP设置为:192.168.2.111

在客户端

“网络设置”中设置IP为:192.168.2.22

可以通过ping命令检测网络是否畅通

(3)在

台计算机

终端先运行服务器

(./serv)

再在客户端

计算机终端上运行客户端

(./clt 192.:168.2.1l 1)就会看到结果(Hello

Wang Lei!You are connected!);运行结果如图4和图5所示

如果未运行服务器

而先运行客户端

将立即提示“Connect:Connection refused”

4 SOCket

性能优化
4.1 解决多路复用
上面

运行过程仅实现了

个客户端接人

在实际情况中

人们往往遇到多个客户端连接服务器端

情况

由于connect


recv


send

都是阻塞性


若资源没有准备好

则

该甬数

进程将进入睡眠状态

无法处理I/O多路复用

在服务器端

serv.c中加入select



它可同时*多个套接字

实现I/O

多路复用

其

原型如下:

该

监视

系列文件描述符

特别是readfds、writefds和exceptfds

如果想知道是否能从标准输入和套接字描述符sockfd读入数据

只要将文件描述符“0”和“sockfd”加入集合readfds中

参数numfds应等于最高文件描述符

值加1

设置该值为sockfd+ 1


它

定大于标准输入

文件描述符“0”

当

select

返回时

readfds

值修改为反映选择

哪个文件描述符可读

重新编译和运行客户端


后

服务器端允许多个客户端接入

服务器端运行结果如图6所示


4.2 最小化报文传输

延时
通过TCP

进行通信时

数据都被拆分成数据块

这样它们就可以封装到给定连接

TCP payload(指TCP数据包中

有效负荷)中

TCP payload

大小取决于几个原因(如最大报文长度和路径)

为了达到较好

性能

应使用尽可能多

可用数据来填充每个报文

当没有足够

数据来填充 payload时(也称为最大报文段长度maximum segment size或MSS)

TCP将采用Nagle算法自动将

些小缓冲区连接到

个报文段中

这样可以通过最小化所发送

报文

数量来提高应用


效率

并减轻整体

网络拥塞

由于这种算法对数据进行合并

试图构成

个完整

TCP报文段

因此会引入

些延时

Socket网络传输很长时间只发送

些较小

报文

比如 telnet


它让用户可以和远程系统进行交互

通常通过

个shell来进行

如果用户被要求用发送报文的前输入


来填充某个报文段

该思路方法绝对不能满足需要

再比如HTTP协议

通常客户机浏览器会产生

个小请求(

条HTTP请求消息)

然后Web服务器就会返回

个更大

响应(Web页面)

最小化传输延时是首要


在这种情况中

Socket可以提供

种解决方案

即禁用Nagle算法

可设置TCP_NODELAY

选项TCP

禁用Nagle算法


使用Samba

实验表明

在服务器上

Samba驱动器上读取数据时

禁用Nagle算法几乎可以加倍提高读性能

4.3 为Bandwidth Delay Product调节TCP窗口
TCP

性能取决于几方面原因

最重要

是链接带宽(link bandwidth)(报文在网络上传输

速率)和往返时间(round-trip time)或RTT(发送报文和接收到另

端

响应的间

延时)

这两个值确定称为BDP(Bandwidth Delay Prod-uct)

内容

BDP给出

种简单

思路方法计算理论上最优

TCP Socket缓冲区大小(其中保存排队等待传输和等待应用

接收

数据)

缓冲区太小

TCP窗口就不能完全打开

这会限制性能;缓冲区太大

则会浪费宝贵

内存资源;设置

缓冲区大小合适

就可完全利用可用带宽

BDP计算公式:
BDP=link bandwidth×RTT
若应用

通过

个100MB/s

局域网通信

其RRT为500ms

则BDP为:50MB/sx0.050/ 8625M=625KB

Linux2.6默认

TCP窗口大小是110KB

这将连接

带宽限制为22M/S

计算思路方法如下:
throughput=window_size/RTT
110 KB/0.050=2.2 MB/s
使用上面计算

窗口大小

得到带宽为12.5 MB/s

即:
625 KB/0 050=12.5 MB/s
差别很大

并且可以为Socket提供更大

吞吐量

可以根据自己

Socket计算最优

缓冲区大小

Socket提供几个Socket选项

其中两个可以用于修改Socket

发送和接收缓冲区

大小

使用SO_SNDBUF和SO_RCVBUF选项来调整发送和接收缓冲区

大小


在Linux 2.6内核中.发送缓冲区

大小由

用户定义

而接收缓冲区会自动加倍

通过计算合理设置缓冲区

大小

Socket网络传输带宽

资源将得到充分利用

从而提高了传输性能

5 结束语
设计和实现

个基于Linux

Socket网络编程

通过在服务器端运行预先编译

可执行文件serv

和在客户端运行预先编译

可执行文件clt

服务器端和客户端建立通信连接

加入select


以后

服务器端可以允许多个客户端接入服务器端

解决了I/O多路复用问题

更加接近实际应用

利用TCP

禁用Nagle算法实现了最小化报文传输

延时

提高了Socket

性能

在网络带宽非常珍贵

现实中

提出了为Bandwidth Delay Product调节TCP窗口

修改


发送和接收缓冲区

大小

完全利用可用

带宽

达到较好

网络传输效果

实际网络传输环境复杂多变

如何达到最理想

网络传输

还需进

步

分析和研究