• CSocket服务器(TCP)


    我的理解:把服务器和客户端的交互工程比喻成外来人员访问公司,每来一个客户端访问,需要服务器的前台经理接待此客户,然后前台经理呼叫一个接待员来将客户带上楼。服务器的两个角色前台经理和接待员就是服务器的两个CSocket对象。

    1、需要生成两个类对象,一个用来监听客户的访问,一个用来接待客户。

      在类向导中新建类名:CSockL和CSockC,重写CSockL的OnAccept函数和CSockC的OnReceive和OnClose函数:

      CSockL(1)、

        void CSockL::OnAccept(int nErrorCode)//有客户连接,就回调此函数
        {
        // TODO: 在此添加专用代码和/或调用基类
        CSockC *p=new CSockC;//每有一个访问,就生成一个CSockC对象指针
        this->Accept(*p);
        //p->GetPeerName()可以用来获取刚刚连接的客户端ip和端口
        CSocket::OnAccept(nErrorCode);
        }

      CSockC(2)、

        void CSockC::OnReceive(int nErrorCode)//有客户发送消息,就回调
        {
        // TODO: 在此添加专用代码和/或调用基类
        char rcv[100];//装从客户端传来的数据
        int rcvLenth=Receive(rcv,sizeof(rcv));//核心处
        rcv[rcvLenth]=0;//消除乱码
        CString ipAddrss;//装发送消息的客户端ip地址
        UINT ipPort;//装端口
        int result=GetPeerName(ipAddrss,ipPort);//获取发送消息客户端的ip和端口

        CTestCSoketServerDlg *p=(CTestCSoketServerDlg*)AfxGetMainWnd();//获取主窗口类指针
        p->ShowInfo(rcv,ipAddrss,ipPort);//调用主窗口类指针的显示函数
        CSocket::OnReceive(nErrorCode);
        }

        (3)、

        void SocketS::OnClose(int nErrorCode)//有客户端断开连接回调
        {
        // TODO: 在此添加专用代码和/或调用基类

        CSocket::OnClose(nErrorCode);
        }

    2、现在已经得到一个我自己定义的类CSockL:CSocket,在Dlg.h中声明一个CSockL的对象,在Dlg.cpp中的打开服务器button中定义

      if(!m_sockl.Create(8080))
      {
      AfxMessageBox(CString("创建套接字失败"));
      return;
      }
      m_sockl.Listen();

      注意:服务器不需要指定ip,指定端口创建套接字之后,就可以用于捕获所有本地客户端活动

      所以直接create之后listen就相当于是服务器了。

      另外使用Create之后不能再使用Bind()函数

    3、如果需要从服务器传数据到客户端

      这时所有的客户端都长连接在了服务器上面,在Accept中可以得到这些客户端的ip,所以只要有ip就可以用sendto来发送了。

     笔记:

    客户端套接字使用Send()函数的时候,是将数据放入TCP系统共有的缓冲区,然后TCP系统在服务器将缓冲区的数据接收,使用的是Receive()函数。在服务器接收的过程中,客户端会一直处于阻塞状态,只有当服务器将缓冲区里面的数据全部接收完了之后,客户端才会开始下一次Send()。

    CSocket与线程配合使用:

    发送端:使用AfxBeginThread()生成一个新的线程,在这个线程里面Send()数据就行了。这里应该加入一个确认发送标志,即每发送完一个包之后,就进入一个死循环,当服务器处理了这个包的数据后,向客户端发送一个确认包,客户端解析这个包之后,退出死循环,再进行下一个包的处理。

    接收端:先把数据全部接收到一个buf里面,注意这个buf应尽可能大一点,否则可能会出现粘包的情况。然后通过判断如果是需要的客户端端口发来数据,就进入AfxBeginThread()线程,在这个线程里面处理数据。处理完了之后,想客户端发送确认包,进行下一次的数据处理。

    根据上面的原理,可以实现CSocket+线程传送文件

  • 相关阅读:
    (转)一次棘手的rootvg更换硬盘处理过程
    mysql:服务器错误代码
    (转)运行跟踪格式化程序
    (转)InnoDB存储引擎MVCC实现原理
    (转)漫谈JVM
    (转)mysql、innodb和加锁分析
    (转)DB2和 Oracle的并发控制(锁)比较
    (转)Mysql主从复制搭建及详解
    BigDecimal 、BigInteger
    Date、DateFormat、SimpleDateFormat、Calendar
  • 原文地址:https://www.cnblogs.com/judes/p/5902068.html
Copyright © 2020-2023  润新知