网络编程 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"信息,客户端也打印收到的信息

服务器端:




客户端:


结果:

相关内容

    暂无相关文章