lmm9407 2021-12-23 14:45 采纳率: 0%
浏览 13

socket编程select 遇到的困惑

编程思路,在主程序中用来向指定服务器发送数据,在线程中用select模型来接收数据。实验中线程只能接收一次,后面select有返回值,显示有可读数据集,但recv却为0。

全局变量:

vector <SOCKET> m_socket;
fd_set fdSocket;

char s1[12];

主程序:

初始化:

        int netID=0;
        
        s1[0]=(netID & 0xff00)>>8;
        s1[1]=netID & 0x00ff;
        s1[2]=0x00;
        s1[3]=0x00;
        s1[4]=0x00;
        s1[5]=0x06;
        s1[6]=0x01;
        s1[7]=0x03;
        s1[8]=0x00;
        s1[9]=0x01;
        s1[10]=0x00;
        s1[11]=0x0A;


    CInitSock initSock;
    
    servAddr.sin_family=AF_INET;
    servAddr.sin_port=htons(502);

m_socket.resize(2);
    m_socket[0]=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    m_socket[1]=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

    FD_ZERO(&fdSocket);
    servAddr.sin_addr.S_un.S_addr=inet_addr("192.168.2.212");
    if(::connect(m_socket[0],(sockaddr*)&servAddr,sizeof(servAddr))>-1)
    {
        m_msg.AddString("1已连接2.212");
        FD_SET(m_socket[0],&fdSocket);
    }
    if(::connect(m_socket[1],(sockaddr*)&servAddr,sizeof(servAddr))>-1)
    {
        m_msg.AddString("2已连接2.212");
        FD_SET(m_socket[1],&fdSocket);
    }

threadinfo.lpdlg=this;

CWinThread* pThread=AfxBeginThread(ThreadFunc,&threadinfo);

发送按钮BTN1:

::send(m_socket[1].s,s1,12,0);

线程代码:

Threadinfo* pInfo=(Threadinfo*)lpParam;

CListBox *pListBox=nullptr;
    pListBox=(CListBox *)pInfo->lpdlg->GetDlgItem(IDC_LIST1);

while(true)
    {
        fd_set fdRead=fdSocket;
        int nRet = select(0, &fdRead, NULL, NULL, NULL);
        if(nRet>0)
        {
            for(int i=0;i<(int)fdSocket.fd_count;i++)
            {
                if(FD_ISSET(fdSocket.fd_array[i],&fdRead))
                {
                    char szText[256];
                    int nRecv=::recv(fdSocket.fd_array[i],szText,strlen(szText),0);
                    szText[nRecv]='\0';
                    CString str1,str2;
                    str1="";
                    for(int j=0;j<nRecv;j++)
                    {
                        str2.Format("%02x ",szText[j]);
                        str1+=str2;
                    }
                    CString msg=szText;
                    pListBox->AddString(str1);
                    FD_CLR(fdSocket.fd_array[i],&fdRead);
                }
            }
        }
    }

执行BTN,第一次的时候数据能接收到。但是后面按下,就一直收不到数据了。有高人能解惑吗?实在发现不了问题出在哪里。

  • 写回答

1条回答 默认 最新

  • hyt_meeyi 2022-12-16 14:59
    关注
    Threadinfo* pInfo=(Threadinfo*)lpParam;
    
    CListBox *pListBox=nullptr;
        pListBox=(CListBox *)pInfo->lpdlg->GetDlgItem(IDC_LIST1);
        fd_set fdRead;
        
    while(true)
    { 
        FD_ZERO(&fdRead);
        FD_SET(sockfd, &fdRead);  // 添加描述符
        int nRet = select(0, &fdRead, NULL, NULL, NULL);
        if(nRet>0)
        {
            for(int i=0;i<(int)fdSocket.fd_count;i++)
            {
                if(FD_ISSET(fdSocket.fd_array[i],&fdRead))
                {
                    char szText[256];
                    int nRecv=::recv(fdSocket.fd_array[i],szText,strlen(szText),0);
                    szText[nRecv]='\0';
                    CString str1,str2;
                    str1="";
                    for(int j=0;j<nRecv;j++)
                    {
                        str2.Format("%02x ",szText[j]);
                        str1+=str2;
                    }
                    CString msg=szText;
                    pListBox->AddString(str1);
                    FD_CLR(fdSocket.fd_array[i],&fdRead);
                }
            }
        }
    }
    
    

    每次循环都需要重新添加一次fd_set内的所有监听socket。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 12月23日

悬赏问题

  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办