VC++网络编程 总结 1

以下的程序是基于阻塞模式下进行编写。没有采用多线程

套接字: 应用程序与网络的接口。
                套接字相当于一个中介,绑定IP地址,端口号,采用TCP/UDP传输
                以套接字为媒介,配合其他函数,来实现网络通信

套接字的功能:   监听、
                            发送数据、
                            接收数据、

监听过程: 服务器 等待客户端连接请求的到来

服务器的监听功能 在特定的 IP地址和端口上进行, 服务器的IP地址和端号必须是固定的   服务器要先启动           

TCP协议和UDP协议的区别:
              TCP:   双方必须建立连接(三次握手,安全可靠), 相当于打电话,
                         数据分段传输,可靠不会有丢失。
                         可以进行流量控制。
              UDP:  双方无需同时在线,
                         不可靠传输,以数据包形式发送。
                         一方只管发送,至于发送成功不成功不管。

基于TCP和UDP的socket编程的区别:
              1. 使用的套接字的类型不同,TCP使用的是流式套接字,UDP使用的是数据报式套接字
              2.  TCP是面向连接的,因此通信双方必须建立连接,连接部分需要我们通过编程实现
                   UDP是无连接的,对通信双方的状态无要求,你随时发你的数据,不需要告诉我什么时候发
              3. TCP编程 相对于 UDP编程 多了: 监听、连接、接收连接部分;       


SOCKET 结构体中:记录了   本地的IP  和  端口号,
                                  记录了   目的地IP  和  端口号。

!!!!!!!!!!!!
想要通过套接字实现和对方的数据接收,该套接字结构体必须既保存了本机的IP和端口,也保存了目的地的IP 和 端口!!!!!!!!


基于TCP的网络应用程序编写(面向连接)
             
 服务器端的程序一定要先启动
       服务器端
             综述: 需要通过两个套接字来实现与客户端的通信, 旧的套接字用来进行监听(是否有客户端进行连接请求)
                         新的套接字实现和客户端进行数据的接收和发送。
                         每一个客户端请求链接时,都会生成一个新的套接字

             第1步: 加载套接字库 
                   
关键语句:WSAStartup(wVersionRequested, &wsaData)

              第2步: 创建用于监听的流式套接字 
                   关键语句: SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0)
                   //  该套接字结构体是空的,未记录本地 以及 目的地 的IP 和 端口

              第3步: 将套接字与本地IP 和 端口 进行绑定  
                  关键语句: bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
                   // 该套接字便记录下了本地IP 和 端口
                   // 绑定后功能:1. 通过套接字可以实现监听,即:客户端有没有请求连接
                                            2.告诉客户端在哪个地址和端口等待数据的到来
                                           注:基于TCP的这两个功能都用到了,基于UDP是只用到了第2个功能

              第4步: 将套接字设置为监听模式
                   关键语句:listen(sockSrv, 5);
                   // 监听的目的是为连接做准备,只有监听到,才能进行连接
                   // 5 代表只准有5客户端等待连接,多余的将抛弃,可以根据自己的要求改动
                   
              第5步: 接收客户端的连接请求
         
          关键语句: SOCKET sockConn = accept(sockSrv, (SOCKADDR *)&addrClient,&len);
                  //  新的套接字应该 既记录了服务器 IP和端口,也记录了客户端的IP和端口
                  //  在没有客户端连接请求到来之前, 程序会一直阻塞在这个函数里。
                  //  用新的套接字来完成与客户端的接收、发送数据,原先的客户端仍然只是监听功能
               
  // TCP协议三次握手建立可靠连接就发生在此步中

              第6步: 用新的套接字与客户端进行数据的收发
                   
关键语句:  send(sockConn, sendbuf, 11, 0);
                                        recv(sockConn, recvBuf1, 11, 0);
                    // 两个函数都是以字节来进行操作的。
                    // 进行数据的收发时,哪条语句放在前面无所谓
                    //因为TCP是有连接的,所以收发函数中没有 参数专门指向客户端的IP和端口
                    // 当没有数据过来时recv会一直等待,处于堵塞状态

              第7步: 关闭新的套接字库
                    
关键语句:   closesocket(sockConn);

               第8步: 关闭旧的套接库和终止对套接字库的使用(如果服务器不是死循环的时候)
                    
关键语句:   closesocket(sockSrv);
                                         WSACleanup();

 客户端
             综述: 需要通过一个套接字来实现与客户端的通信

             第1步: 加载套接字库 
                   
关键语句:WSAStartup(wVersionRequested, &wsaData)

              第2步: 创建流式套接字 
                   关键语句: SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0)
                   //  该套接字结构体是空的,未记录本地 以及 目的地 的IP 和 端口

              第3步: 发出连接请求
                  关键语句: connect(sockSrv, (SOCKADDR*)&addrSrv, sizeof(addrSrv));
                   //  addrSrv是服务器的IP 和 端口
                   //  该函数应该会把本地的IP 和 端口发送过去。
                   //  TCP的三次握手发生在此时期
                   // 此时套接字记录下 服务器的IP 和端口 ,也会记录下本机客户端的IP 和 端口 ,
                       要不然为什么以后发送数据时只需要套接字就可以,而不需要再填写服务器的 IP 和 端口呢

              第4步: 用套接字与客户端进行数据的收发
                   
关键语句:  send(sockConn, sendbuf, 11, 0);
                                        recv(sockConn, recvBuf1, 11, 0);
                    // 两个函数都是以字节来进行操作的。
                    // 进行数据的收发时,哪条语句放在前面无所谓
                    //因为TCP是有连接的,所以收发函数中没有 参数专门指向客户端的IP和端口
                   // 当没有数据过来时recv会一直等待,处于堵塞状态

               第5步: 关闭套接库和终止对套接字库的使用(如果客户端不是死循环的时候)
                    
关键语句:   closesocket(sockSrv);
                                         WSACleanup();

       

基于UDP的网络应用程序编写(面向无连接)
        UDP下服务器和客户端这种概念不是很强化,也就说其实无所谓谁是服务器端谁是客户端

    服务器端
             综述: 需要通过一个套接字来实现与客户端的通信, 套接字用来通信,不用来监听

             第1步: 加载套接字库 
                   
关键语句:WSAStartup(wVersionRequested, &wsaData)

              第2步: 创建数据报式套接字 
                   关键语句: SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0)
                   //  该套接字结构体是空的,未记录本地 以及 目的地 的IP 和 端口

              第3步: 将套接字与本地IP 和 端口 进行绑定  
                  关键语句: bind(sockSrv, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR));
                   // 该套接字便记录下了本地IP 和 端口
                   // 绑定后功能:告诉客户端在哪个地址和端口等待数据的到来                                   

              第4步: 用套接字与客户端进行数据的收发
                   
关键语句: recvfrom(sockSrv, recvBuf, 11, 0, (SOCKADDR *)&addrClient,&len);
                                       sendto(sockSrv, sendbuf, strlen(sendbuf) + 1, 0, (SOCKADDR *)&addrClient, sizeof(SOCKADDR));
                    // 两个函数都是以字节来进行操作的。
                    // 进行数据的收发时,哪条语句放在前面无所谓
                    //因为UCP是有连接的,所以收发函数中必须有专门的参数保存着客户端的IP和端口
                    //此时的套接字我也不清楚有没有保存着客户端的IP 和端口,因为 再次发送数据的话仍然用的是此语句,仍有需要                          IP和端口的参数
                   // 当没有数据过来时recvfrom会一直等待,处于堵塞状态

               第5步: 关闭套接字库和终止对套接字库的使用(如果服务器不是死循环的时候)
                    
关键语句:   closesocket(sockSrv);
                                         WSACleanup();

 客户端
             综述: 需要通过一个套接字来实现与客户端的通信          

             第1步: 加载套接字库 
                     
关键语句:WSAStartup(wVersionRequested, &wsaData)

              第2步: 创建数据报式套接字 
                   关键语句: SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0)
                   //  该套接字结构体是空的,未记录本地 以及 目的地 的IP 和 端口

              第4步: 用套接字与客户端进行数据的收发
                   
关键语句: recvfrom(sockSrv, recvBuf, 11, 0, (SOCKADDR *)&addrClient,&len);
                                       sendto(sockSrv, sendbuf, strlen(sendbuf) + 1, 0, (SOCKADDR *)&addrClient, sizeof(SOCKADDR));
                    // 两个函数都是以字节来进行操作的。
                    // 进行数据的收发时,哪条语句放在前面无所谓
                    //因为UCP是有连接的,所以收发函数中必须有专门的参数保存着客户端的IP和端口
                    //此时的套接字我也不清楚有没有保存着客户端的IP 和端口,因为 再次发送数据的话仍然用的是此语句,仍有需要                          IP和端口的参数
                    // 当没有数据过来时recvfrom会一直等待,处于堵塞状态

               第5步: 关闭套接字库和终止对套接字库的使用(如果服务器不是死循环的时候)
                    
关键语句:   closesocket(sockSrv);
                                         WSACleanup();       

         

其他一些琐碎的小问题
   
         
recv和send函数都是按照字节进行接收的。
               比如客户端中用send发送数据,则服务器中用recv接收消息,客户端中send()的数目和服务器中recv()的数目没有对应关系,原因:发送时用send发送了20个字节,用recv去接收的时候可能只接收了10个字节,

             另外:服务器和客户端的收发可以同时进行,不用考虑谁先发送谁先接收

猜你喜欢

转载自blog.csdn.net/qq_29824717/article/details/81482286