网络编程 TCP,网络编程tcp
网络编程 TCP,网络编程tcp
网络编程的传输层协议一般分为UDP和TCP 其中TCP协议是面向连接的,可靠的,流式服务的协议。简而言之就是安全性完整性更高的,但效率低于UDP的协议。 本文将重点涉及linux下具体的采取TCP协议的网络编程代码实现。 首先最基本的要有两份代码,即服务器端和客户端各一份。 服务器端编程流程如下:1.首先要创建一个套接字socket,其本质为文件描述符
Int socket(int domain,int type,int protocol);
Domain: 协议簇 宏PF_INET 表示TCP IPV4的协议簇,其的值与地址簇AF_INET相等
Type: 选择的协议 宏SOCK_STREAM表示流式,即TCP的
Protocol 前两个参数的构成下选择具体的协议,一般写0表示取默认
最后成功返回描述符,失败返回-1
2. 由于第一步中只是对socket进行协议族选择,并未指定地址族。
因此要使用bind函数 将 服务器的Ip地址和端口号 与 创建的socket绑定起来。
Int bind(int sockfd,struct sockaddr *addr,int addrlen);
sockfd:表示第一步sockfd函数的返回值,即sock描述符
第二个参数是一个结构体指针,这结构体存放的是地址簇协议和socket地址值,但由于这个结构体总不能满足我们需求,因此我们用了linux下的新定义的结构体,如下
Struct sockaddr_in
{
Sa_family_t sin_family;//地址簇
U_int16_t sin_port //端口号 但由于网络字节序(大端模式),一般用htons函数转换端口号
Strcut in_addr sin_addr;//ip地址
}
Struct in_addr
{
U_int32_t addr;//一般给地址是字符串,因此需要用inet_addr(const char *)
}
因此这个函数的第二个参数要强转成Struct sockaddr_in*类型。
最后一个参数表示参数二指向的结构体大小。
成功返回0,失败返回-1
3.Listen 监听,即创建一个监听队列
Int listen(int sockfd,int backlog);
Backlog:监听队列的最大长度。
成功返回0,失败返回-1
这个并非阻塞函数,只是创建一个监听队列去存放待处理的客户端连接。
4. Accept 从listen创建的监听队列中接受连接
Int accept(int sockfd,struct sockaddr *addr,int * addrlen);
返回值:获取到和客户连接的文件描述符,这个描述符才是之后服务器端收发数据函数会使用到的描述符
Addr:用来记录客户端的ip地址和端口号
int * addrlen:是第二参数结构体的长度的地址,注意 bind传入的是长度,这个是长度的地址
这个函数会阻塞,即监听的队列无描述符时阻塞
5.Recv/send 收发数据
ssize_t recv(int fd,void *buf,size_t len,int flags)
ssize_t send(int fd,const void *buf,size_t len ,int flags)
第一参数是accept返回的描述
第二个参数是接收/发送缓冲区地址
第三个是缓冲区长度
第四个参数是一些控制,目前写0就好
成功返回发送/接受成功的数据长度,失败返回-1
6.Close 关闭连接
int close (int fd);
服务器端要关闭sockfd描述符和accept返回的描述符
客户端流程:
具体函数实现和服务器端大同小异,bind这步命名可有可无,因为服务器端要命名才能让客户端识别要链接那个端口号,而客户端就只有自己这个连接,系统会默认分配sock地址的。
1.创建Socket:
2.Connect 发起连接
Int connect(int sockfd,struct sockaddr*addr,int addrlen);
addr :存放要链接的服务器ip和端口号
3.Recv/send 收发数据
4.Close关闭连接,因为没有accept这一步,所以只用关闭sockfd就好
下面演示具体的例子 客户端发送数据,服务器端打印数据和并发给客户端"I Know"信息,客户端也打印收到的信息
服务器端:
客户端:
结果:
评论暂时关闭