孙鑫MFC(14)--网络编程

孙鑫MFC(14)--网络编程

//-----------网络编程-----------------

//--------------服务器程序-------------

//所要包含的库文件

#include <Winsock2.h>

#include <stdio.h>

//需要在工程设置链接库中添加ws2_32.lib

1、套接字(socket)

//由美国伯克利大学在Unix上推出了一种应用程序访问通信协议的操作系统调用SOCKET,从而使程序员可以很方便地访问TCP/IP,开发出各种网络应用程序。

2、网络字节顺序

//不同的计算机存放多字节值的顺序不同,有是高位先存,有的低位先存

//在网络协议中需要制定网络字节顺序, TCP/IP协议使用16位整数和32位整数的高位先存格式

3、客户机/服务器模式

Client/Server

基于客户机/服务器模式的TCP/IP

2009年12月3日 - Fly - 飛

4、Windows Sockets 的实现

从Berkeley Sockets扩展而来,对他进行了重要扩充,提供了一些异步函数,增加了符合消息驱动特性的网络事件异步选择机制。

三种套接字的类型

2009年12月3日 - Fly - 飛

有链接及无连接的 Socket编程

2009年12月3日 - Fly - 飛2009年12月3日 - Fly - 飛

二、示例

//---------------面向有链接的网络通信--------------------

1、加载套接字库

WSAStartup()  //加载套接字库,并进行套接字库的版本协商(确定使用哪个版本的套接字库)

2009年12月3日 - Fly - 飛

//下面代码来自帮助,演示了如何使用1.1版 的WinSock库

    WORD wVersionRequested;

 WSADATA wsaData;

 int err;

 

 wVersionRequested = MAKEWORD( 1, 1 );

 //相当于wVersionRequested = 0x101;

 

 err = WSAStartup( wVersionRequested, &wsaData );

 if ( err != 0 ) {

  /* Tell the user that we could not find a usable */

  /* WinSock DLL.                                  */

  //printf("找不到winsock.dll/n");

  return;

 }

 

 /* Confirm that the WinSock DLL supports 1.1.*/

 /* Note that if the DLL supports versions greater    */

 /* than 1.1 in addition to 1.1, it will still return */

 /* 1.1 in wVersion since that is the version we      */

 /* requested.                                        */

 

 if ( LOBYTE( wsaData.wVersion ) != 1 ||

        HIBYTE( wsaData.wVersion ) != 1 ) {

  /* Tell the user that we could not find a usable */

  /* WinSock DLL.                                  */

  WSACleanup( );

  return;

 }

 

 /* The WinSock DLL is acceptable. Proceed. */

 

//-----------------------------------------------------

  SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);

  //对于TCP/IP协议的套接字,只能用AF_INET(PF_INET)地址族

  //SOCK_STREAM基于TCP协议的套接字

  //0为自动选择协议

 

  if(scokSrv == SOCKET_ERROR)

  {

    printf("创建Sockets出错/n");

    WSACleanup();

    return;

  }

 

  SOCKADDR_IN addrSrv;      //定义地址结构

  addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  //表示自动接收并发给任何地址

  //htonl()函数表示转为网络字节序

  addrSrv.sin_family = AF_INET;       //指定地址族

  addrSrv.sin_port = htons(6000);     //指定端口号

 

  //绑定本地地址及端口号

  bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

  listen(sockSrv,5)     //监听,等待链接的最大数为5

 

  SOCKADDR_IN addrClinet;       //用于接收客户端套接字

  int len = sizeof(SOCKADDR);

 

  while(1)

  {

    //accept()函数,用于接受客户端发来的信息,并新创建一个符合客户端的套接字作为返回值

    SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClinet,&len);

    char sendBuf[100];

   

    //将字符串信息格式化到发送缓存中

    sprintf(sendBuf,"Welcome %s to my home",inet_ntoa(addrClinet.sin_addr));

    //inet_ntoa()函数表示将in_addr结构体转为网络字节格式

   

    send(sockConn,sendBuf,strlen(sendBuf) + 1,0);

    //采用新建的套接字进行传送,加1是为了给发给客户端的信息加上'/0'介绍符

    //最后个参数默认为0

   

    char recvBuf[100];

   

    int iRect;

  

    //接收客户端信息

    iRect = recv(sockConn,recvBuf,100,0);

    recvBuf[iRect] = '/0';

    //打印信息

    printf("%s/n",recvBuf);

    //关闭套接字

    closesocket(sockConn);

   

  }

 

//---------------------------------------------------- 

//==============客户端代码============

    WORD wVersionRequested;

 WSADATA wsaData;

 int err;

 

 wVersionRequested = MAKEWORD( 1, 1 );

 

 err = WSAStartup( wVersionRequested, &wsaData );

 if ( err != 0 ) {

  /* Tell the user that we could not find a usable */

  /* WinSock DLL.                                  */

  return;

 }

 

 /* Confirm that the WinSock DLL supports 1.1.*/

 /* Note that if the DLL supports versions greater    */

 /* than 1.1 in addition to 1.1, it will still return */

 /* 1.1 in wVersion since that is the version we      */

 /* requested.                                        */

 

 if ( LOBYTE( wsaData.wVersion ) != 1 ||

        HIBYTE( wsaData.wVersion ) != 1 ) {

  /* Tell the user that we could not find a usable */

  /* WinSock DLL.                                  */

  WSACleanup( );

  return;

 }

 

 /* The WinSock DLL is acceptable. Proceed. */

 

 //---------------------------------

 

 SOCKET sockClient = socket(AF_INET,SOCK_STREAM,0);

 

 if(scokClient == SOCKET_ERROR)

    {

        printf("创建Sockets出错/n");

        WSACleanup();

        return;

    }

 SOCKADDR_IN addrSrv;

 addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

 addrSrv.sin_family = AF_INET;

 addrSrv.sin_port = htons(6000);

 if(SOCKET_ERROR == connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)))

 {

        printf("链接服务器出错/n");

        WSACleanup();

        return;

 }

 

    /*

 int iRect;

  

    //接收客户端信息

    iRect = recv(sockConn,recvBuf,100,0);

    recvBuf[iRect] = '/0';

    这一行代码不可少!因为recv函数不会自动将数据缓冲末尾

    设为表示数据结束的空中止符(`/0`),因此,一不留神就会出现缓冲区越界。

    当然也可以在调用recv函数前先将缓冲区清0(用ZeroMemory或memset),不过

    还是建议加上这一句。*/

   

    char recvBuf[100];

    recv(sockConn,recvBuf,100,0);

   

 printf("%s/n",recvBuf);

 send(sockClient,"This is lisi",strlen("This is lisi") + 1,0);

 closesocket(sockClient);

 WSACleanup();

//-------------------------------------------------------------------------

//===========面向无连接的通信============

//--------服务器端---------------

    WORD wVersionRequested;

 WSADATA wsaData;

 int err;

 

 wVersionRequested = MAKEWORD( 1, 1 );

 

 err = WSAStartup( wVersionRequested, &wsaData );

 if ( err != 0 ) {

  /* Tell the user that we could not find a usable */

  /* WinSock DLL.                                  */

  return;

 }

 

 /* Confirm that the WinSock DLL supports 1.1.*/

 /* Note that if the DLL supports versions greater    */

 /* than 1.1 in addition to 1.1, it will still return */

 /* 1.1 in wVersion since that is the version we      */

 /* requested.                                        */

 

 if ( LOBYTE( wsaData.wVersion ) != 1 ||

        HIBYTE( wsaData.wVersion ) != 1 ) {

  /* Tell the user that we could not find a usable */

  /* WinSock DLL.                                  */

  WSACleanup( );

  return;

 }

 

 /* The WinSock DLL is acceptable. Proceed. */

 

//----------------------------------------------------------------

//无需循环监听,无需接受并单独创建套接字

 

 SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);

 SOCKADDR_IN addrSrv;

 addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

 addrSrv.sin_family = AF_INET;

 addrSrv.sin_port = htons(6000);

 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

 SOCKADDR_IN addrClient;

 int len = sizeof(SOCKADDR);

 char recvBuf[100];

 recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);

 printf("%s/n",recvBuf);

 closesocket(sockSrv);

 WSACleanup();

//------------------------客户端-----------------------------

#include <winsock2.h>

#include <stdio.h>

#pragma comment(lib,"ws2_32.lib");

void main()

{

 WORD wVersionRequested;

 WSADATA wsaData;

 int err;

 

 wVersionRequested = MAKEWORD( 1, 1 );

 //相当于wVersionRequested = 0x101;

 

 err = WSAStartup( wVersionRequested, &wsaData );

 if ( err != 0 ) {

  /* Tell the user that we could not find a usable */

  /* WinSock DLL.                                  */

  //printf("找不到winsock.dll/n");

  return;

 }

 

 /* Confirm that the WinSock DLL supports 1.1.*/

 /* Note that if the DLL supports versions greater    */

 /* than 1.1 in addition to 1.1, it will still return */

 /* 1.1 in wVersion since that is the version we      */

 /* requested.                                        */

 

 if ( LOBYTE( wsaData.wVersion ) != 1 ||

        HIBYTE( wsaData.wVersion ) != 1 ) {

  /* Tell the user that we could not find a usable */

  /* WinSock DLL.                                  */

  WSACleanup( );

  return;

 }

 

 /* The WinSock DLL is acceptable. Proceed. */

 SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);

 SOCKADDR_IN addrSrv;

 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));

 closesocket(sockClient);

 WSACleanup();

}

//---------------------------------------------


以上转自:http://mxmkeep.blog.163.com/blog/

====================================================================================

1.加载套接字库
2.WSAStartup
The Windows Sockets WSAStartup function initiates use of Ws2_32.dll by a process.

int WSAStartup(
  WORD wVersionRequested, 
  LPWSADATA lpWSAData 
);

typedef struct WSAData {
  WORD                  wVersion;
  WORD                  wHighVersion;
  char                  szDescription[WSADESCRIPTION_LEN+1];
  char                  szSystemStatus[WSASYS_STATUS_LEN+1];
  unsigned short        iMaxSockets;
  unsigned short        iMaxUdpDg;
  char FAR *            lpVendorInfo;
} WSADATA, *LPWSADATA;

socket
The Windows Sockets socket function creates a socket that is bound to a specific service provider.

SOCKET socket(
  int af,      
  int type,    
  int protocol 
);

int bind(
  SOCKET s,                         
  const struct sockaddr FAR *name,  
  int namelen                       
);

struct sockaddr_in{
    short            sin_family;
    unsigned short      sin_port;
    struct   in_addr      sin_addr;
    char               sin_zero[8];
};

Vc++6.0 error LNK2005: _main already defined in UdpClient.obj UDP时出现的问题

 

/**************************************************服务器端************************************************/

#include <Winsock2.h>
#include <stdio.h>

void main()
{
 //加载套接字库,套接字库的版本协商 WSAStartup
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;

 wVersionRequested = MAKEWORD( 1, 1 );

 err = WSAStartup( wVersionRequested, &wsaData );
 if ( err != 0 )
 {                         
  return;
 }

 if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
 {
  WSACleanup( );//终止套接字库的使用
  return;
 }

 SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);
 SOCKADDR_IN addrSrv;
 addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
 addrSrv.sin_family = AF_INET;
 addrSrv.sin_port = htons(6000);

 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

 char recvBuf[100];
 char sentBuf[100];
 char tempBuf[200];

 SOCKADDR_IN addrClient;
 int len = sizeof(SOCKADDR); //返回地址结构的长度

 while (1)
 {
  recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len); //接收地址(SOCKADDR*)&addrClient
  if ('q'==recvBuf[0])
  {
   sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len); //发送地址
   printf("Chat end!/n");
   break;
  }
  sprintf(tempBuf,"%s say : %s",inet_ntoa(addrClient.sin_addr),recvBuf);//对方的IP地址addrClient.sin_addr
  printf("%s/n",tempBuf);

  printf("Please input data:/n");
  gets(sentBuf);//从键盘上获取输入流
  sendto(sockSrv,sentBuf,strlen(sentBuf)+1,0,(SOCKADDR*)&addrClient,len);
 
 }
 closesocket(sockSrv); //关闭套接字
 WSACleanup();   //终止对套接字库的使用
}

/**************************************************客户端端************************************************/

#include <Winsock2.h>
#include <stdio.h>

void main()
{
 //加载套接字库,套接字库的版本协商 WSAStartup
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;

 wVersionRequested = MAKEWORD( 1, 1 );

 err = WSAStartup( wVersionRequested, &wsaData );
 if ( err != 0 )
 {                         
  return;
 }

 if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 )
 {
  WSACleanup( );//终止套接字库的使用
  return;
 }

 SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);
 SOCKADDR_IN addrSrv;
 addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
 addrSrv.sin_family = AF_INET;
 addrSrv.sin_port = htons(6000);

 char recvBuf[100];
 char sentBuf[100];
 char tempBuf[200];

 int len = sizeof(SOCKADDR); //返回地址结构的长度

 while (1)
 {
  printf("Please input data:/n");
  gets(sentBuf);//从键盘上获取输入流
  sendto(sockClient,sentBuf,strlen(sentBuf)+1,0,(SOCKADDR*)&addrSrv,len);

  recvfrom(sockClient,recvBuf,100,0,(SOCKADDR*)&addrSrv,&len);
  if ('q'==recvBuf[0])
  {
   sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)&addrSrv,len);
   printf("Chat end!/n");
   break;
  }
  sprintf(tempBuf,"%s say : %s",inet_ntoa(addrSrv.sin_addr),recvBuf);
  printf("%s/n",tempBuf);

 }
 closesocket(sockClient);
 WSACleanup();              
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值