设为首页 加入收藏

TOP

Linux TCP协议的基础编程模型
2014-11-24 02:38:54 来源: 作者: 【 】 浏览:1
Tags:Linux TCP 协议 基础 编程 模型

一、TCP协议的基础编程模型


TCP是面向连接的通信协议,采用客户机-服务器模式。套接字的全部工作流程如下所述:


1.服务器启动进程,调用Socket创建一个基于TCP协议的流套接字描述符。


2.其次,服务进程调用bind命名套接字,将套接字描述符绑定到本地地址和本地端口上,至此Socket的半相关描述---{协议,本地地址,本地端口}---完成。


3.再次,服务器端调用listen,开始侦听客户端的Socket连接请求。


4.接下来,客户端创建套接字描述符,并且调用connect向服务端提交连接请求。服务器端接收到客户端连接请求后,调用accept接受,并创建一个新的套接字描述符与客户端建立连接,然后原套接字描述符继续侦听客户端的连接请求。


5.客户端与服务器端的新套接字进行数据传送,调用write或send向对方发送数据,调用read或recv接收数据。


6.在数据交流完毕后,双方调用close或者shutdown半闭套接字。


二、UNIX基于TCP的通信相关函数


1.Socket的创建---系统调用Socket


#include


#include


int socket(int domain, int type, int protocol);


返回值:成功返回创建的套接字描述符,否则返回-1并置errno。


说明:函数socket创建一个Socket描述符。


domain 指定发送通信的域,即套接字的协议族。有AF_UNIX(本地主机通信)和AF_INET(Internet地址IPV4协议)。


type 指定通信类型,有SOCK_STREAM,SOCK_DGRAM和SOCK_RAW。


Protocol指定了该套接字描述符上的一个特殊的协议书,比如TCP、UDP等,一般设置为0。


2.Socket的命名---系统调用bind


#include


#include


int bind(int s, const struct sockaddr *name, int namelen);


返回值:成功返回0,否则返回-1并置errno。


函数bind命名一个套接字,它为该套接字描述符分配一个半相关属性。


s 调用socket创建的套接字。


指针name指向通用套接字的协议地址结构,包括协议、地址和端口信息等。


namelen 指定该协议地址结构长度,一般定义为sizeof(sockaddr_in)。


关于套接字地址属性结构:


struct sockaddr{


u_short sa_family; /* 协议族 */


char sa_data[14]; /* 最多14字节的协议地址 */


};


不同的协议有不同的地址描述方式,为了便于编码处理,每种协议族都定义了自己的套接字地址属性结构,比如协议族AF_INET使用结构sockaddr_in描述套接字地址信息,该结构定义在头文件中。


struct sockaddr_in{


short sin_family; /* 16位的地址协议族(AF_INET)*/


u_short sin_port; /* 16位的端口地址 */


struct in_addr sin_addr; /* 32位的IP地址 */


char sin_zero[8]; /* 预留 */


};


struct in_addr{


u_long s_addr;


};


预留成员作用是使结构sockaddr_in与结构sockaddr的长度相同。


IP地址转换---完成IP地址的字符串格式与32位4字节整型之间的转换。


unsigned long inet_addr(char *ptr);


int inet_aton(char *ptr, stuct in_addr *addrptr);


char *inet_ntoa(struct in_addr inaddr);


字节顺序转换---实现主机字节顺序与网络字节顺序之间转换


#include


#include


u_short htons(u_short hostshort); /*将16位整数由主机字节顺序转换成网络字节顺序*/


u_long htonl(u_long hostlong); /*将32位整数由主机字节顺序转换成网络字节顺序*/ u_short ntohs(u_short netshort); /*将16位整数由网络字节顺序转换成主机字节顺序*/


u_long ntohl(u_long netlong); /*将32位整数由网络字节顺序转换成主机字节顺序*/


例:命名套接字描述符s的协议为AF_INET,地址为“127.0.0.1”,端口号为1000。


struct sockaddr_in sockaddr1; /*申请地址结构空间*/


memset(&sockaddr1, 0 , sizeof(sockaddr1)); /*清空空间*/


sockaddr1.sin_family = AF_INET;


sockaddr1.sin_addr.s_addr = inet_addr(“127.0.0.1”); /*IP地址转换为整型赋值*/


sockaddr1.sin_port = htons(1000); /*端口号 主机字节顺序转换为网络字节顺序*/


如需系统自动指定套接字的IP地址,则


sockaddr1.sin_addr.s_addr = htonl(INADDR_ANY); /*自动分配地址*/


3.Socket的侦听---系统调用listen


#include


#include


int listen(int s, int backlog);


返回值:成功返回0,否则返回-1并置errno。


TCP服务器端必须调用listen函数才能使套接字进入侦听状态。


s 调用socket创建、bind命名的套接字。


backlog 确定套接字s接收的最大数目,如果到达最大的连接数,服务器端将向客户端发出ECONNRERUSED错误。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Java使窗口最小化为图标 下一篇一个Linux C做的TCP文件传输的代码

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: