跳至主要内容

【转】VxWorks套接口

int m_socket;
 
// Open a socket
       m_socket = socket(AF_INET, SOCK_STREAM, 0);
 
第一个参数domain说明我们网络程序所在的主机采用的通讯协族(AF_UNIX和AF_INET等).
AF_UNIX只能够用于单一的Unix系统进程间通信, 而AF_INET是针对Internet的, 因而可以允许在远程主机之间通信.
VxWorks套接字仅支持Internet域地址族, 不支持UNIX域地址族. 因此在需要domain参数的函数中, 使用AF_INET作为函数参数值.
第二个参数type说明我们网络程序所采用的通讯协议(SOCK_STREAM, SOCK_DGRAM等). SOCK_STREAM表明我们用的是TCP协议, 这样会提供按顺序的,可靠,双向,面向连接的比特流. SOCK_DGRAM 表明我们用的是UDP协议, 这样只会提供定长的,不可靠,无连接的通信.
此外,还有SOCK_RAW代表是原始协议套接字.
第三个参数protocol, 由于我们指定了type, 所以这个地方我们一般只要用0来代替就可以了.
socket为网络通讯做基本的准备, 成功打开则返回一个套接字描述符, 如果失败则返回ERROR.套接字描述符是一个标准的I/O系统文件描述符(fd, file descriptor), 可以被close(), read(), write()和ioctl()函数使用.
 
// Make the socket sending alive messages when connected
int flag = 1;
setsockopt(m_socket, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(flag));
 
// increase receive buffer size
flag = SOCKET_BUF_SIZE;
setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char*)&flag, sizeof(flag));
 
// increase send buffer size
setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, (char*)&flag, sizeof(flag));
 
// try without the nagle algorithm
flag = 1;
setsockopt (m_socket, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof (flag));
 
// Prevent "bind error 48"!
flag = 1;
setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(flag));
 
SOCK_STREAM型套接字支持SO_KEEPALIVE选项,SOCK_DGRAM型套接字不支持。缺省没有启用保活机制。基本套接口选项SO_KEEPALIVE用于检测对方主机是否崩溃,避免(服务器)永远阻塞于TCP连接的输入。设置该选项后,如果2小时内在此套接口的任一方向都没有数据交换,TCP就自动给对方发一个保持存活探测分节(keep alive probe)。这是一个对方必须响应的TCP分节. 它会导致以下三种情况:对方接收一切正常:以期望的ACK响应。2小时后,TCP将发出另一个探测分节。对方已崩溃且已重新启动:以RST响应。套接口的待处理错误被置为ECONNRESET,套接口本身则被关闭。对方无任何响应:源自berkeley的TCP发送另外8个探测分节,相隔75秒一个,试图得到一个响应。在发出第一个探测分节11分钟15秒后若仍无响应就放弃。套接口的等待处理错误被置为ETIMEOUT,套接口本身则被关闭。如ICMP错误是"host unreachable(主机不可达)",说明对方主机并没有崩溃,但是不可达,这种情况下待处理错误被置为EHOSTUNREACH。
 
IPPROTO_TCP: TCP套接口
 
尽管有许多TCP选项可供程序员操作,而我们却最关注如何处置其中的两个选项,它们是TCP_NODELAY和 TCP_CORK,这两个选项都对网络连接的行为具有重要的作用。
TCP_NODELAY和TCP_CORK基本上控制了包的"Nagle化",Nagle化在这里的含义是采用Nagle算法把较小的包组装为更大的帧。现在让我们假设某个应用程序发出了一个请求,希望发送小块数据。我们可以选择立即发送数据或者等待产生更多的数据然后再一次发送两种策略。如果我们马上发送数据,那么交互性的以及客户/服务器型的应用程序将极大地受益。例如,当我们正在发送一个较短的请求并且等候较大的响应时,相关过载与传输的数据总量相比就会比较低,而且,如果请求立即发出那么响应时间也会快一些。以上操作可以通过设置套接字的TCP_NODELAY选项来完成,这样就禁用了Nagle算法。
 
SO_REUSEADDR选项的设置将套接口设置成重新使用旧的地址(IP地址加端口号)而不等待.
如果一个socket绑定了某个端口,该socket正常关闭或程序退出后,在一段时间内该端口依然保持被绑定的状态,其他程序(或者重新启动的原程序)无法绑定该端口。这由 TCP 套接字状态TIME_WAIT引起。该状态在套接字关闭后约保留 2 到 4 分钟。在TIME_WAIT状态退出之后,套接字被删除,该地址才能被重新绑定而不出问题。等待TIME_WAIT结束可能是令人恼火的一件事,特别是如果您正在开发一个套接字服务器,就需要停止服务器来做一些改动,然后重启。幸运的是,有方法可以避开TIME_WAIT状态。可以给套接字应用SO_REUSEADDR套接字选项,以便端口可以马上重用。
 
// Fill in the address descriptor
struct sockaddr_in addr;                    // 服务器的地址
bzero((char*)&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(Port);                // 默认端口
addr.sin_addr.s_addr = inet_addr(IpAddress);
 
// Bind the socket to the address
bind(m_socket, (struct sockaddr*)&addr, sizeof(addr));
 
// Listen for a client to connect (max n simultaneously)
listen(m_socket, n);
 
在使用TCP协议时,一般服务端任务先使用socket调用得到一个描述符,然后使用bind调用将一个名字与socket描述符连接起来,对于Internet域就是将Internet地址绑定到socket.
之后,服务端使用listen调用指出最大的被拒绝连接次数。然后就可以使用accept调用等待客户端发起连接。
bind函数用于给套接字分配名字。该函数分配一个网络地址(也称为"名字")给指定的套接字,以便其他处理可以连接它或给它发送数据。当使用socket()创建一个套接字时,它属于一个地址族但并没有分配名字。
listen函数允许连接套接字,并指定最大的被拒绝连接次数。当用listen()允许连接后,通过accept()函数接受连接。
一般服务端可能在accept返回后创建一个新的任务进行与客户的通信,或者直接创建一个新的任务来调用accept,原来的任务则继续等待另一个连接。
 

评论

此博客中的热门博文

【转】嵌入式开发中使用DDD进行调试

 在嵌入式程序开发过程中,程序员要进行大量的调试,以此验证程序的正确性,修改潜在的错误。调试器对于程序员来说是不可或缺的必备工具。在Linux环境中,有很多调试工具和调试辅助工具,例如GDB、XXGDB、RHIDE、XWPE、GVD和DDD等。其中,DDD是命令行调试器的图形前端,除了一般的程序调试功能以外,还具有交互式图形数据显示的功能。它在嵌入式应用开发中也十分出色。本文主要讲述DDD(Data Display Debugger)的使用方法。      1.认识DDD     GNU DDD是命令行调试程序,如GDB、DBX、WDB、Ladebug、JDB、XDB、Perl Debugger或Python Debugger的可视化图形前端。它特有的图形数据显示功能(Graphical Data Display)可以把数据结构按照图形的方式显示出来。DDD最初源于1990年Andreas Zeller编写的VSL结构化语言,后来经过一些程序员的努力,演化成今天的模样。DDD的功能非常强大,可以调试用C\C++、Ada、 Fortran、Pascal、Modula-2和Modula-3编写的程序;可以超文本方式浏览源代码;能够进行断点设置、回溯调试和历史纪录编辑;具有程序在终端运行的仿真窗口,并在远程主机上进行调试的能力;图形数据显示功能(Graphical Data Display)是创建该调试器的初衷之一,能够显示各种数据结构之间的关系,并将数据结构以图形化形式显示;具有GDB/DBX/XDB的命令行界面,包括完全的文本编辑、历史纪录、搜寻引擎。     DDD是开源软件,用户可以去 http://www.cs.tubs.de/softech/ddd/ 下载.rpm格式的DDD源码文件。      图1显示的是DDD的主窗口。它主要由选单栏、工具条、数据窗口、源文件窗口、机器码窗口、控制台和命令工具窗口等几部分组成。其中,数据窗口用于观察复杂的数据结构,在删除数据之后,显示仍然有效;源文件窗口显示源代码、断点和当前执行到达的位置,选择该窗口中的"Display"项,可以显示任意表达式的值;机...

【转】U-boot代码分析

/* * S3C44B0 CPU启动代码。 * 蔡军生 2005/07/17 * */ /* * 包含配置文件。 */ #include <config.h> /* 添加版本说明. 2005/07/16 */ #include <version.h> /* * 中断向量表. */ /* × 声明标量是全局函数,CPU加电启动后,就从这里执行代码。 */ .globl _start _start:        b       reset                   /* 跳到复位中断开始位置。 */         add        pc, pc, #0x0c000000         add        pc, pc, #0x0c000000         add        pc, pc, #0x0c000000         add        pc, pc, #0x0c000000         add        pc, pc, #0x0c000000     ...

【转】cs8900网卡的移植至基于linux2.6内核的s3c2410平台

cs8900网卡的移植至基于linux2.6内核的s3c2410平台(转) 2008-03-11 20:58 硬件环境:SBC-2410X开发板(CPU:S3C2410X) 内核版本:2.6.11.1 运行环境:Debian2.6.8 交叉编译环境:gcc-3.3.4-glibc-2.3.3 第一部分 网卡CS8900A驱动程序的移植 一、从网上将Linux内核源代码下载到本机上,并将其解压: #tar jxf linux-2.6.11.1.tar.bz2 二、打开内核顶层目录中的Makefile文件,这个文件中需要修改的内容包括以下两个方面。 (1)指定目标平台。 移植前:         ARCH?= $(SUBARCH) 移植后: ARCH            :=arm (2)指定交叉编译器。 移植前: CROSS_COMPILE ?= 移植后: CROSS_COMPILE   :=/opt/crosstool/arm-s3c2410-linux-gnu/gcc-3.3.4-glibc-2.3.3/bin/arm-s3c2410-linux-gnu- 注:这里假设编译器就放在本机的那个目录下。 三、添加驱动程序源代码,这涉及到以下几个方面。(1)、从网上下载了cs8900.c和cs8900.h两个针对2.6.7的内核的驱动程序源代码,将其放在drivers/net/arm/目录下面。 #cp cs8900.c ./drivers/net/arm/ #cp cs8900.h ./drivers/net/arm/ 并在cs8900_probe()函数中,memset (&priv,0,sizeof (cs8900_t));函数之后添加如下两条语句: __raw_writel(0x2211d110,S3C2410_BWSCON); __raw_writel(0x1f7c,S3C2410_BANKCON3); 注:其原因在"第二部分"解释。 (2)、修改drivers/net/arm/目录下的Kconfig文件,在最后添加如...