MFC——10.网络编程基础

来源:互联网 发布:微信订餐软件 编辑:程序博客网 时间:2024/06/15 07:47

Lesson10:网络编程基础

 

网络编程是计算机编程的一个重要分支,是网络通信的基础,网络编程主要用到了Windows系统系统提供的socket。网络通信又分为基于TCP和基于UDP两种。本文主要讲解基于TCP和UDP的网络编程基础知识。

1.      基于TCP的socket编程


1.1  TCP服务器

#include <winsock2.h>#include <stdio.h>//#include <iostream>#pragma comment(lib,"ws2_32.lib")       //静态加入一个lib文件,也就是库文件ws2_32.lib文件,它提供了对以下网络相关API的支持void main(){         /********            首先设定通信版本        **************/         WORDwVersionRequested;         WSADATAwsaData;         interr;          wVersionRequested= MAKEWORD(1, 1);     //请求的通信版本为(1,1)          err= WSAStartup(wVersionRequested, &wsaData);      //调用WSAStartup函数         if(err != 0)                   return;     //如果返回值不为0,表示没有对应的WinSockDLL.则返回          if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)         {                   WSACleanup();     //如果版本的高字节不为1,低字节不为1,则返回。                                   return;         }          //1创建套接字         SOCKETsockSrv = socket(AF_INET, SOCK_STREAM,0);           //(1地址族AF_INET 或 PF_INET,2socket类型SOCK_STREAM或 SOCK_DGRAM,3与特定的地址家族相关的协议)     调用成功返回新的socket数据类型的套接字描述符                 //2绑定套接字到本地地址和端口          /*structsockaddr_in{                   short            sin_family;         //地址族                   unsignedshort      sin_port;        //端口号                   struct   in_addr     sin_addr;      //套接字的主机IP地址                   char   sin_zero[8];      //填充数,使sockaddr_in和sockaddr结构长度一样         }*/          SOCKADDR_INaddrSrv;         addrSrv.sin_addr.S_un.S_addr= htonl(INADDR_ANY);          //调用htonl函数进行转换主机字节序为TCP/IP网络字节序//addrSrv是一个结构体,里面有一个结构体变量sin_addr,里面包含共用体S_un,然后是共用体成员S_addr,inet_addr函数进行主机字节序转换为网络字节序         addrSrv.sin_family= AF_INET;         addrSrv.sin_port=htons(6000);             //端口号为6000,需要1024以上端口号,网络字节序,需要转换,htonl和htons不同在于转换数据的范围         bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));        //绑定套接字和地址的  函数   (1指定要绑定的套接字,2该套接字的本地地址信息,是指向sockaddr结构的指针变量,3指定该地址的长度)          //3调用listen函数,将套接字设置为监听模式,准备接受客户请求         listen(sockSrv,5);       //(套接字描述符,最大的等待连接队列数)                 //4等待客户请求到来         //5用返回的套接字和客户端进行通信         //6返回,等待另一个客户请求         //7关闭套接字                 SOCKADDR_INaddrClient;     //定义一个地址结构的变量,用来接受客户端的地址信息,在循环结构中用到         intlen = sizeof(SOCKADDR);         while(1)              //死循环,一直监听,持续运行         {                     SOCKETsockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);            //(1处于监听状态的主机服务器套接字描述符,2指向buffer指针连接实体地址,保存了发起客户端的ip信息和端口信息,3指向整型指针,包含返回地址结构的长度),返回一个新的连接的套接字描述符,用他和客户端通信,先前的套接字继续监听客户连接请求                                     //发送数据                   /*intsend(                            SOCKETs,      //建立连接所对应的套接字描述符,不是监听的套接字                            constchar FAR * buf,      //一个buff指针,包含将要传送的数据                            int len,                 //buffer中数据的长度                            intflags                //设定send的调用行为                            );*/                    charsendBuf[100];                   sprintf_s(sendBuf,"Welcome%s to http://www.sunxin.org",inet_ntoa(addrClient.sin_addr));    //把格式化的数据写入某个字符串,将客户端地址传给字符串里的%s,                   send(sockConn,sendBuf, strlen(sendBuf)+1, 0);                    //接受数据                   /*intrecv(             The Windows Socketsrecv function receives data from a connected socket.                            SOCKETs,               //建立连接的套接字                            charFAR* buf,           //接受数据的buff                            intlen,                 //buff的长度                            intflags                //设定接受函数的调用行为                            );*/                    charrecvBuf[100];                   recv(sockConn,recvBuf, strlen(recvBuf) + 1, 0);                   printf("%s\n",recvBuf);                   closesocket(sockConn);         }}

1.2  TCP客户端

#include <winsock2.h>#include <stdio.h>//#include <iostream>#pragma comment(lib,"ws2_32.lib")void main(){         /********            首先设定通信版本        **************/         WORDwVersionRequested;         WSADATAwsaData;         interr;          wVersionRequested= MAKEWORD(1, 1);      //请求的通信版本为(1,1)          err= WSAStartup(wVersionRequested, &wsaData);  //调用WSAStartup函数         if(err != 0)                   return;            //如果返回值不为0,表示没有对应的WinSockDLL.则返回          if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)         {                   WSACleanup();     //如果版本的高字节不为1,低字节不为1,则返回。                                   return;         }          //1创建套接字         SOCKETsockClient= socket(AF_INET, SOCK_STREAM, 0);           //(1地址族AF_INET 或 PF_INET,2socket类型SOCK_STREAM或 SOCK_DGRAM,3与特定的地址家族相关的协议)     调用成功返回新的socket数据类型的套接字描述符          /*intconnect(         //The Windows Socketsconnect function establishes a connection to a specifed socket.                   SOCKETs,                                //套接字                   conststruct sockaddr FAR*  name,        //地址结构体指针,用来设定链接的服务器地址信息                   intnamelen                              //地址结构体的长度                   );*/         //2连接服务器         SOCKADDR_INaddrSrv;                           //SOCKADDR_IN是一个结构体变量         addrSrv.sin_addr.S_un.S_addr= inet_addr("127.0.0.1");       //addrSrv是一个结构体,里面有一个结构体变量sin_addr,里面包含共用体S_un,然后是共用体成员S_addr,inet_addr函数进行主机字节序转换为网络字节序         addrSrv.sin_family= AF_INET;         addrSrv.sin_port= htons(6000);    //主机字节序转换为网络字节序          connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));          //3和服务器端口进行通信(接受服务器发送的信息)         charrecvBuf[100];         recv(sockClient,recvBuf, strlen(recvBuf) + 1, 0);         printf("%s\n",recvBuf);         send(sockClient,"This is zhangsan", strlen("This is zhangsan") + 1, 0);          //4关闭套接字         closesocket(sockClient);         WSACleanup();                //终止对套接字库的使用         system("pause");             //用于防止闪退}

2.      基于UDP的socket编程

2.1   UDP服务器

#include <winsock2.h>#include <stdio.h> #pragma comment(lib,"ws2_32.lib") void main(){         /********            首先设定通信版本        **************/         WORDwVersionRequested;         WSADATAwsaData;         interr;          wVersionRequested= MAKEWORD(1, 1);            //请求的通信版本为(1,1)          err= WSAStartup(wVersionRequested, &wsaData);      //调用WSAStartup函数         if(err != 0)                   return;        //如果返回值不为0,表示没有对应的WinSockDLL.则返回          if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)         {                   WSACleanup();      //如果版本的高字节不为1,低字节不为1,则返回。                                   return;         }          //1创建套接字         SOCKETsockSrv = socket(AF_INET, SOCK_DGRAM, 0);      //(1地址族AF_INET 或 PF_INET,2socket类型SOCK_STREAM或 SOCK_DGRAM,3与特定的地址家族相关的协议)     调用成功返回新的socket数据类型的套接字描述符          //2绑定套接字到本地地址和端口         SOCKADDR_INaddrSrv;         addrSrv.sin_addr.S_un.S_addr= htonl(INADDR_ANY);       //调用htonl函数进行转换主机字节序为TCP/IP网络字节序         addrSrv.sin_family= AF_INET;         addrSrv.sin_port= htons(6000);              //端口号为6000,1024以上端口号,需要网络字节序,需要转换,htonl和htons不同在于转换数据的范围          bind(sockSrv,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR));     //绑定函数   (1指定要绑定的套接字,2该套接字的本地地址信息,是指向sockaddr结构的指针变量,3指定该地址的长度)          /*intrecvfrom(             The Windows Socketsrecvfrom function receives a datagram and stores the source address.                   SOCKETs,             //套接字                   charFAR* buf,        //接收数据的buffer                  int len,              //buffer的长度                  int flags,            //设定recvfrom函数的调用行为         structsockaddr FAR* from,      //地址结构体指针,接收发送数据方的地址信息                   intFAR* fromlen      //函数返回值,返回地址结构的大小                   );*/          //3等待接收数据recvfrom          SOCKADDR_INaddrClient;     //定义一个地址结构的变量,用来接受客户端的地址信息,在循环结构中用到         intlen = sizeof(SOCKADDR);         charrecvBuf[100];          recvfrom(sockSrv,recvBuf, strlen(recvBuf) + 1, 0, (SOCKADDR*)&addrClient, &len);         printf("%s\n",recvBuf);          //4关闭套接字         closesocket(sockSrv);         WSACleanup();                     //终止对套接字库的使用         system("pause");                   //用于防止闪退}

2.2   UDP客户端

#include <winsock2.h>#include <stdio.h> #pragma comment(lib,"ws2_32.lib") void main(){         /********            首先设定通信版本        **************/         WORDwVersionRequested;         WSADATAwsaData;         interr;          wVersionRequested= MAKEWORD(1, 1);         //请求的通信版本为(1,1)          err= WSAStartup(wVersionRequested, &wsaData);    //调用WSAStartup函数         if(err != 0)                   return;          //如果返回值不为0,表示没有对应的WinSockDLL.则返回          if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)         {                   WSACleanup();     //如果版本的高字节不为1,低字节不为1,则返回。                                   return;         }          //1创建套接字         SOCKETsockClient = socket(AF_INET, SOCK_DGRAM, 0);           //(1地址族AF_INET 或 PF_INET,2socket类型SOCK_STREAM或 SOCK_DGRAM,3与特定的地址家族相关的协议)     调用成功返回新的socket数据类型的套接字描述符          /*intsendto(   The Windows Sockets sendtofunction sends data to a specific destination.                   SOCKETs,                    //套接字                   constchar FAR * buf,        //包含将要发送的数据                  int len,                     //数据的长度                   intflags,                   //设置sendto函数调用行为                   conststruct sockaddr FAR * to,   //地址结构体指针,设定目的套接字的地址信息                   inttolen                         //地址结构体的长度                   );*/          //2向服务器发送数据(sendto)         SOCKADDR_INaddrSrv;         addrSrv.sin_addr.S_un.S_addr= inet_addr("127.0.0.1");         addrSrv.sin_family= AF_INET;         addrSrv.sin_port= htons(6000);          sendto(sockClient,"Hello", strlen("Hello") + 1, 0, (SOCKADDR*)&addrSrv,sizeof(SOCKADDR));          //3关闭套接字         closesocket(sockClient);         WSACleanup();           //终止对套接字库的使用         system("pause");          //用于防止闪退}

 

1 0
原创粉丝点击