TCP、UDP服务器与客户端网络编程实现

TCP
     面向连接的     可靠的     字节流服务
UDP
     无连接     不可靠的     数据报服务
IP
     无连接     不可靠的     无状态的

RUDP:介于TCP和UDP中间,两者取其中。

TCP编程流程:
服务器:socket    bind    listen    accept    recv/send    close
客户端:socket    connect    send/recv    close

TCP编码流程:
服务器:
实现TCP需要的头文件:
     #include
     #include
     #include
     #include

需要的函数原型:
   ①  int socket(int domain, int type, int protocol);//创建socket
   返回值:-1 出错,只要返回值>=0即正确
                  返回的值,也是文件描述符   socket文件描述符
   domain:协议簇      一般用AF_INET(TCP/IP)协议簇
   type:在该协议簇下选择的具体的协议    TCP:SOCK_STREAM      UDP:SOCK_DGRAM
   pro:具体的协议下更具体的协议:默认给0

   ②  int bind(int sockfd, struct sockaddr *seraddr, socklen_t);
   sockfd:socket返回的文件描述符
   struct sockaddr *seraddr:服务器端的ip地址
   socklen_t:第二个参数的长度

   为了了解这个函数我们还需要知道:
   如何标识一台主机?
   需要知道IP地址+端口号
   struct sockaddr_in
   {
      sa_family_t sin_family;//地址族
      u_int16_t sin_port;//端口号
      struct in_addr sin_addr;IP地址
   }

   struct in_addr
   {
        u_int32_t s_addr;//无符号32位整型值
   }

端口号的转化函数:将IP地址转化成整型值
TCP、UDP服务器与客户端网络编程实现_第1张图片
   端口号取值范围:0-65535   但0-1024(无法使用,系统预留)   1024-5000保留   一般我们用5000以上端口号

   地址转化函数:
在这里插入图片描述
主机字节序:
   大端模式:高位存低地址
   小端模式:高位存高地址

网络字节序:都用的大端模式(如果主机是小端模式不经过转化在网络中传输数据就会乱套)

   ③  int listen(int sockfd, int size);//给sockfd启动监听
   sockfd:socket返回的socket值监听sockfd套接字。监听:等客户端连接
   size:指定已完成连接队列的大小。一般为:size + 1
         两个队列:
               已完成连接的队列
               正在完成连接的队列

   ④  int accept(int sockfd, struct sockaddr* cliaddr, int len);
   sockfd:接收连接的套接字
   struct coskaddr cliaddr:客户端连接时内核自动填充
   int *len:填充的大小
   返回值:返回维护本次连接的文件描述符,服务器和客户端通讯时通过accept返回的文件描述符进行通讯

   ⑤  int recv(int c, void *buff ,int buffsize, int flag);//获取数据
   int c:标识从哪个客户端来获取数据
   void *buff:读到的数据存放在哪
   int buffsize:buff缓冲区的大小有多少,一次最多读多少个字节的数据
   int flag:不用默认给0

   ⑥int send(int c, void *buff,int datasize, int flag);  发送数据
   int c:将数据发送给谁
   void *buff:发送的数据从哪开始
   int datasize:数据的大小
   int flag:不用默认给0

服务器端编码流程:
     1.调用socket()创建套接字;
     2.定义strcuct sockaddr_in ser,cli;
     3.对地址族,端口号,IP地址进行赋值;
     4.bind()进行命名;
     5.listen进行启动监听
     6.while(1)循环
     {
          int c = accept();获取连接
          while(1)//一个客户端与服务器进行多次通讯
          {recv()/send();}//收发
     }//一个服务器可以多次处理不同客户端的连接
     7.close();

如下图为TCP服务器的创建:
TCP、UDP服务器与客户端网络编程实现_第2张图片

客户端:
需要的函数原型:
   ①  int socket(int domain, int type, int protocol);//与前面一样

   ②  int connect(int sockfd, (struct sockaddr*)seraddr, int len);//发起连接
   int sockfd:上面socket返回的文件描述符
   (struct sockaddr*)seraddr:和哪个服务器进行连接,服务器的地址和端口号
   int len:连接的长度
返回:-1 连接失败 返回>-1 成功

   ③  int send(int c, void *buff,int datasize, int flag);//发起连接

   ④  int recv(int c, void *buff ,int buffsize, int flag);//获取数据

   ⑤  close();//发送数据

客户端编码流程:
     1.socker();创建套接字
     2.connect();发起连接和服务器进行连接
     3.while(1)//多次接受发送数据
          {
               send()/recv();多次
          }
     4.close();

下图为TCP客户端的创建:
TCP、UDP服务器与客户端网络编程实现_第3张图片
TCP服务器与客户端连接测试如图:
一个客户端与服务器的连接(连接成功):
TCP、UDP服务器与客户端网络编程实现_第4张图片
多个客户端与服务器的连接(连接失败):
TCP、UDP服务器与客户端网络编程实现_第5张图片
UDP编程流程:
服务器:socket    bind   recvfrom/sendto    close
客户端:socket    sendto/recvfrom    close

UDP编码流程:
服务器:
需要的函数原型:
   ①  int socket(int domain, int type, int protocol);//创建socket
   int type:需要UDP :SOCK_DGRAM协议

   ②  int bind(int sockfd,struct sockaddr* seraddr,int size);//UDP是无连接,不可靠数据报服务,所以不需要监听,无linsten;也不需要accpet

   ③  int recvfrom(int sockfd, void *buff, int size, int flag, struct sockaddr *cliaddr, int *addrlen);//接收客户端的数据+客户端地址信息
   int sockfd:从哪获取数据
   void *buff:将数据放在哪
   int size:buff缓冲区的大小有多少,一次最多读多少个字节的数据
   int flag:默认0
   struct sockaddr *cliadd, int *addrlen:保留客户端的IP地址与端口号

   ④  int sendto(int sockfd,void * buff, int datalen, int flag, struct sockaddr *cliaddr, int addrlen);//发送数据(指定数据发送给哪个客户端)
   int sockfd,void * buff, int datalen, int flag:发送的数据
   struct sockaddr *cliaddr, int addrlen:发送给谁

   ⑤  int close(int sockfd);//关闭
如下图为服务器的创建:
TCP、UDP服务器与客户端网络编程实现_第6张图片

客户端:
需要的函数原型:
   ①  int socket(int domain, int type, int protocol);//创建socket
   int type:需要UDP :SOCK_DGRAM协议

   ②  int recvfrom(int sockfd, void *buff, int size, int flag, struct sockaddr *cliaddr, int *addrlen);//接收客户端的数据+客户端地址信息

   ③  int sendto(int sockfd,void * buff, int datalen, int flag, struct sockaddr *cliaddr, int addrlen);//发送数据(指定数据发送给哪个客户端)

   ④  int close(int sockfd);//关闭
如下图为客户端的创建:
TCP、UDP服务器与客户端网络编程实现_第7张图片
TCP、UDP服务器与客户端网络编程实现_第8张图片
UDP服务器与客户端连接测试如图:
一个客户端与服务器的连接(连接成功):
TCP、UDP服务器与客户端网络编程实现_第9张图片
多个客户端与服务器的连接(连接成功):
TCP、UDP服务器与客户端网络编程实现_第10张图片

你可能感兴趣的:(计算机网络,计算机网络,网络编程,TCP,服务器,客户端)