zoukankan      html  css  js  c++  java
  • 简单的客户端-服务器模型

    1、服务器端代码

     1 #pragma comment(lib, "ws2_32.lib")
     2 
     3 #include <WinSock2.h>
     4 #include <iostream>
     5 
     6 using namespace std;
     7 
     8 bool LoadSockLib()
     9 {
    10     WSADATA wsaData;
    11     if(SOCKET_ERROR == WSAStartup(MAKEWORD(2, 2), &wsaData))
    12     {
    13         DWORD dwError(0);
    14         dwError = GetLastError();
    15         cout << "加载套接字库失败,错误代码:" << dwError << endl;
    16         return false;
    17     }
    18     return true;
    19 }
    20 
    21 int main()
    22 {
    23     if(!LoadSockLib())
    24     {
    25         exit(-1);
    26     }
    27 
    28     SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    29     if(INVALID_SOCKET == sock)
    30     {
    31         DWORD dwError(0);
    32         dwError = GetLastError();
    33         cout << "获取套接字失败,错误代码:" << dwError << endl;
    34         exit(-2);
    35     }
    36 
    37     sockaddr_in addrBind;
    38     addrBind.sin_family = AF_INET;
    39     addrBind.sin_port = htons(3456);
    40     addrBind.sin_addr.S_un.S_addr = INADDR_ANY;
    41 
    42     sockaddr_in addrClient;
    43 
    44     int iRetVal = 0;
    45     if(iRetVal = bind(sock, (sockaddr*)&addrBind, sizeof(addrBind)))
    46     {
    47         DWORD dwError(0);
    48         dwError = GetLastError();
    49         cout << "绑定套接字失败,错误代码:" << dwError << endl;
    50         exit(-3);
    51     }
    52 
    53     listen(sock, 5);
    54     int len = sizeof(sockaddr);
    55     cout  << "服务器已经准备好,正在等待客户端的连接..." << endl;
    56     SOCKET sockClient = accept(sock, (sockaddr*)&addrClient, &len);
    57     cout << inet_ntoa(addrClient.sin_addr) << "已连接。" << endl;
    58 
    59     char szRecBuf[512] = {0};
    60     char szSendBuf[512] = {0};
    61     while(true)
    62     {
    63         cout << "请给客户端发送消息:" << endl;
    64         cin >> szSendBuf;
    65         send(sockClient, szSendBuf, strlen(szSendBuf), 0);
    66         cout << "消息已经发送给客户端,等待其回复..." << endl;
    67 
    68         iRetVal = recv(sockClient, szRecBuf, 512, 0);
    69         cout << "127.0.0.1 回复说:" << szRecBuf << endl;
    70         
    71         memset(szRecBuf, 0, 512);
    72         memset(szSendBuf, 0, 512);
    73     }
    74 
    75     return 0;
    76 }

    2、客户端代码

     1 #pragma comment(lib, "ws2_32.lib")
     2 
     3 #include <WinSock2.h>
     4 #include <iostream>
     5 
     6 using namespace std;
     7 
     8 bool LoadSockLib()
     9 {
    10     WSADATA wsaData;
    11     if(SOCKET_ERROR == WSAStartup(MAKEWORD(2, 2), &wsaData))
    12     {
    13         DWORD dwError(0);
    14         dwError = GetLastError();
    15         cout << "加载套接字库失败,错误代码:" << dwError << endl;
    16         return false;
    17     }
    18     return true;
    19 }
    20 
    21 int main()
    22 {
    23     if(!LoadSockLib())
    24     {
    25         exit(-1);
    26     }
    27 
    28     SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    29     if(INVALID_SOCKET == sock)
    30     {
    31         DWORD dwError(0);
    32         dwError = GetLastError();
    33         cout << "获取套接字失败,错误代码:" << dwError << endl;
    34         exit(-2);
    35     }
    36 
    37     SOCKADDR_IN addr;
    38     addr.sin_family = AF_INET;
    39     addr.sin_port = htons(3456);
    40     addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    41 
    42     int iRetVal = 0;
    43     iRetVal = connect(sock, (SOCKADDR*)&addr, sizeof(addr));
    44     if(SOCKET_ERROR == iRetVal)
    45     {
    46         DWORD dwError(0);
    47         dwError = GetLastError();
    48         cout << "连接服务器失败,错误代码:" << dwError << endl;
    49         exit(-3);
    50     }
    51 
    52     char szRecBuf[512] = {0};
    53     char szSendBuf[512] = {0};
    54     while(true)
    55     {
    56         cout << "等待服务器发送消息..." << endl;
    57         iRetVal = recv(sock, szRecBuf, 512, 0);
    58         cout << "127.0.0.1 说:" << szRecBuf << endl;
    59 
    60         cout << "请回复服务器:" << endl;
    61         cin >> szSendBuf;
    62         send(sock, szSendBuf, strlen(szSendBuf), 0);
    63 
    64         memset(szRecBuf, 0, 512);
    65         memset(szSendBuf, 0, 512);
    66     }
    67     return 0;
    68 }

    执行结果:

    服务器端

    客户端

    3、我的疑问

    虽然程序是正确的执行的了,但是其中却还有存有许多的疑问。

    1. 以前看书时,说的是,服务器端监听一个固定的端口,当收到连接请求时,用accept接受请求并返回一个新生成的套接字,该服务器套接字继续监听该固定端口。于是问题来,我运行该程序,当服务器端进行通信时,我用netstat查看了一下端口,发现监听的是3456(我指定的监听端口),其状态为listen,然而,通信的端口还是3456,也就是服务器和客户端通信使用的端口还是3456,因为我现在一个客户端,所以没问题,但是,将程序的监听功能放在一个单独的线程中执行的话,那么就可以同时和多个客户端通信,那难熬还是使用同一个端口么?下面是我查看端口的截图

    未完待续。。。

  • 相关阅读:
    SpringMVC视图解析器
    FreeMarker介绍
    一篇很全面的freemarker教程
    request,session,application
    nav布局 在线演示 DIVCSS5
    opacity
    java 某字符串在另一字符串中是否存在
    bochs 使用讲解
    使用VS2015搭建Lua开发环境
    Zip文件格式
  • 原文地址:https://www.cnblogs.com/lit10050528/p/3662523.html
Copyright © 2011-2022 走看看