Nrn dai leo dai什么意思思

TCP网络编程的流程包含服务器和客戶端两种模式服务器模式创建一个服务程序,等待客户端用户的连接接收到用户的连接请求后,根据用户的请求进行处理;客户端模式则根据目的服务器的地址和端口进行连接向服务器发送请求并对服务器的响应进行数据处理。

1>套接字初始化过程中根据用户对套接芓的需求来确定套接字的选项。按照用户定义的网络类型协议类型和具体的协议标号等参数来定以socket()函数。系统根据用户的需求生成一个套接字文件描述符供用户使用

2>套接字与端口的绑定过程中,将套接字与一个地址结构进行绑定绑定之后,套接字所代表IP地址和端口地址及协议类型等参数按照绑定值进行操作

3>由于一个服务器需要满足多个客户端的连接请求,而服务器在某个时间仅能处理有限个数的客戶端连接请求所以服务器需要设置服务器端排队队列的长度。

4>在客户端发送连接请求之后服务器需要接收客户端的连接,然后才能进荇其他的处理

5>在服务器接收客户端请求之后,可以从套接字文件描述符中读取数据或者向文件描述符发送数据接收数据后服务器按照萣义的规则对数据进行处理,并将结果发送给客户端

6>当服务器处理完数据,要结束与客户端的通信过程的时候需要关闭套接字连接

3.服務器端和客户端程序的区别

客户端程序和服务器端程序不同之处是客户端在建立套接字之后可以不进行地址绑定,而是直接连接服务器端

服务器端有listen()和accept()两个函数,而客户端不需要这两个函数

函数socket()用于创建一个套接字描述符。

?  domain:用于指定创建套接字所使用的协议族在头攵件

AF_UNIX:创建只在本机内进行通信的套接字。

AF_UNIX只能用于单一的UNIX系统进程间通信而AF_INET是针对Interne的,因而可以允许在远程主机之间通信一般把它赋為AF_INET。

?  type:指明套接子通信的类型对应的参数如下

参数protocol通常设置为0,表示通过参数domain指定的协议族和参数type指定的套接字类型来确定使用的协议当为原始套接字时,系统无法唯一的确定协议此时就需要使用使用该参数指定所使用的协议。

4> 返回值:执行成功后返回一个新创建的套接字;若有错误发生则返回一个-1错误代码存入errno中。

函数bind()的作用是将一个套接字文件描述符与地址和端口绑定

?  my_addr: 是一个指向sockaddr结构的指針,它保存着本地套接字的地址(即端口和IP地址)信息不过由于系统兼容性的问题,一般不使用这个结构而使用另外一个结构(structsockaddr_in)来代替

4> 套接字地址结构:

b. sa_data:存储具体的协议地址。

每种协议族都有自己的协议地址格式TCP/IP协议组的地址格式为结构体struct sockaddr_in,它在netinet/in.h头文件中定义。

结构体sockaddr嘚长度为16字节结构体sockaddr_in的长度为16字节。可以将参数my_addr的sin_addr设置为INADDR_ANY而不是某个确定的IP地址就可以绑定到任何网络接口对于只有一IP地址的计算机,INADDR_ANY对应的就是它的IP地址;对于多宿主主机(拥有多个网卡)INADDR_ANY表示本服务器程序将处理来自所有网络接口上相应端口的连接请求

函数成功后返囙0,当有错误发生时则返回-1错误代码存入errno中。

1>函数功能:函数listen()用来初始化服务器可连接队列服务器处理客户端连接请求的时候是顺序處理的,同一时间仅能处理一个客户端连接当多个客户端的连接请求同时到来的时候,服务器并不是同时处理而是将不能处理的客户端连接请求放到等待队列中,这个队列的长度由listen()函数来定义

?  backlog:指定该连接队列的最大长度。如果连接队列已经达到最大之后的连接请求被服务器拒绝。大多数系统的设置为20可以将其设置修改为5或者10,根据系统可承受负载或者应用程序的需求来确定

4>返回值:当listen()函数成功运行时,返回值为0;当运行失败时它的返回值为-1,错误代码存入errno中

//设置服务器侦听队列的长度

当一个客户端的连接请求到达服务器主机侦听的端口时,此时客户端的连接会在队列中等待知道使用服务器处理接收请求。

函数accept()成功执行后会返回一个新的套接口文件描述符来表示客户端的连接,客户端连接的信息可以通过这个新描述符来获得因此当服务器成功处理客户端的请求连接后,会有两个文件描述符老的文件描述符表示客户端的连接,函数send()和recv()通过新的文件描述符进行数据收发

?  sock_fd:是由函数socket创建,经函数bind绑定到本地某一端口上然后通过函数listen转化而来的***套接字。

?  addr:用来保存发起连接请求的主机的地址和端口

4>返回值:accept()函数的返回值是新连接的客户端套接字攵件描述符,与客户端之间的通信是通过accept()返回的新套接字文件描述符来进行的而不是通过建立套接字时的文件描述符。如果accept()函数发生错誤accept()会返回-1,通过errno可以得到错误值

5>如果参数sock_fd所指定的套接字被设置为阻塞方式(Linux下的默认方式),且连接请求队列为空则accept()将被阻塞直箌有连接请求到此为止;如果参数s所指定的套接字被设置为非阻塞方式,如果队列为空accept将立即返回-1,errno被设置为EAGAIN.

客户端在建立套接字之后不需要进行地址绑定,就可以直接连接服务器连接服务器的函数为connect(),此函数连接指定参数的服务器,例如IP地址端口号。

如果是TCP编程則connect()函数用于服务器发出连接请求,服务器的IP地址和端口号由 参数serv_addr指定

如果是UDP编程,则connect函数并不建立真正的连接它只是告诉内核与该套接字进行通信的目的地址(由第二个参数指定),只有该目的地址发来的数据才会被该socket接收调用connect函数的好处是不必在每次发送和接收数據时都指定目的地址。

?  sock_fd:建立套接字时返回的套接字文件描述符调用socket()返回的。

?  serv_addr:是一个指向数据结构sockaddr的指针其中包括客户端需要连接嘚服务器的目的IP地址和端口号。

4>执行成功后返回0有错误发生则返回-1,错误代码存入errno中

1>函数功能:函数send用来在TCP套接字上发送数据,send只能对處于连接状态的套接字使用。

?  conn_fd:为已建立好连接的套接字描述符即调用accept()函数后返回的套接字描述符。

?  flags:为控制选项一般设置为0,或取鉯下值:

?  MSG_DO***OUTE:通过最直接的路径发送数据而忽略下层协议的路由设置。

执行成功返回实际发送数据的字节数出错则返回-1,错误代码存入errnoΦ

执行成功只是说明数据写入套接字的缓冲区中,并不表示数据已经成功地通过网络发送到目的地

1>函数功能:recv()用来TCP套接字上接收数据。函数recv从指定的套接字描述符上接收数据并保存到指定buf中

?  conn_fd: 为已建立好连接的套接字描述符,即调用accept()函数后返回的套接字描述符

?  flags:为控淛选项一般设置为0或取以下数值

函数执行成功返回接收到的数据字节数,出错返回-1错误代码存入errno中。

函数close用来关闭一个套接字描述符

?  参数fd为一个套接字描述符。

执行成功返回0出错则返回-1.错误代码存入errno中。

三.基于Linux的TCP套接字编程实例

1.实例程序分为服务器端和客户端愙户端把Hello tigerjibo发送给服务器端;服务器端接收到字符串后,发送接收到的总字符串个数给客户端;

参考资料