• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            山寨:不是最好的,是最適合我們的!歡迎體驗(yàn)山寨 中文版MSDN

            Blog @ Blog

            當(dāng)華美的葉片落盡,生命的脈絡(luò)才歷歷可見。 -- 聶魯達(dá)

            常用鏈接

            統(tǒng)計(jì)

            積分與排名

            BBS

            Blog

            Web

            最新評論

            啟動服務(wù)流程代碼

            //主對話框啟動服務(wù)
            void CTCPUDPDlg::OnBtnStartServer() 

            //Server對話框繼承類CSocketComm的CreateSocket
            bool CServer::CreateSock(LPCTSTR strServerName, int nProtocol, int nType, UINT uOptions)

            //啟動服務(wù),主要實(shí)現(xiàn)啟動套接字(socket();setsockopt();bind()(UDP服務(wù)端需要);listen()(TCP服務(wù)端需要禎聽);closesocket())
            bool CSocketComm::CreateSocket(LPCTSTR strServerName, int nProtocol, int nType, UINT uOptions)

            //啟動Socket線程
            bool CSocketComm::WatchServerSocket()

            UINT WINAPI CSocketComm::SocketServerThreadProc(LPVOID pParam)
            //服務(wù)端線程

            void CSocketComm::ServerRun()//Server主線程函數(shù)

            附主要函數(shù)流程具體代碼
            bool CSocketComm::CreateSocket(LPCTSTR strServerName, int nProtocol, int nType, UINT uOptions)
            {
                
            // 如果已經(jīng)打開,則返回false
                if ( IsOpen() )
                    
            return false;

                SOCKADDR_IN sockAddr 
            = 0 };
                
            //地址設(shè)定 //SOCKET
                SOCKET sock = socket(nProtocol, nType, 0);//unsigned int 0~4294967295 
                if (INVALID_SOCKET != sock)
                
            {
                    sockAddr.sin_port 
            = htons( GetPortNumber( strServerName ) );
                    
            if ( 0 != sockAddr.sin_port)
                    
            {
                        sockAddr.sin_addr.s_addr 
            = htonl( INADDR_ANY );
                        sockAddr.sin_family 
            = nProtocol;
                        
            if (uOptions & SO_REUSEADDR) //設(shè)定相關(guān)選項(xiàng)
                        {
                            BOOL optval 
            = TRUE;
                            
            if (SOCKET_ERROR == setsockopt( sock, SOL_SOCKET, SO_REUSEADDR,(char *&optval,sizeof( BOOL )))
                            
            {
                                closesocket( sock );
                                
            return false;
                            }

                        }

                        
            if (nType == SOCK_DGRAM) //如果是UDP協(xié)議
                        {
                            
            if (uOptions & SO_BROADCAST)//如果允許廣播
                            {
                                BOOL optval 
            = TRUE;
                                
            if (SOCKET_ERROR == setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *&optval, sizeof(BOOL)))
                                
            {
                                    closesocket( sock );
                                    
            return false;
                                }

                                m_bBroadcast 
            = true;// 設(shè)定變量
                            }

                            m_hMutex 
            = CreateMutex(NULL, FALSE, NULL);// 如果需要廣播,則需要設(shè)定進(jìn)程互斥
                            if (NULL == m_hMutex)
                            
            {
                                closesocket( sock );
                                
            return false;
                            }

                        }

                        
            if ( SOCKET_ERROR == bind(sock, (LPSOCKADDR)&sockAddr, sizeof(SOCKADDR_IN)))// 綁定一個本地地址
                        {
                            closesocket( sock );
                            m_bBroadcast 
            = false;
                            
            if (NULL != m_hMutex)
                                CloseHandle( m_hMutex );
                            m_hMutex 
            = NULL;
                            
            return false;
                        }

                        
            if (SOCK_STREAM == nType)// 如果是TCP連接
                        {
                            
            if ( SOCKET_ERROR == listen(sock, SOMAXCONN))
                            
            {
                                closesocket( sock );
                                
            return false;
                            }

                        }

                        m_hSocket 
            = (HANDLE) sock;// 保存socket
                        return true;
                    }

                    
            else
                        SetLastError(ERROR_INVALID_PARAMETER); 
            //不能找到端口
                    closesocket( sock );// 刪除socket
                    return false;
                }

                
            else//創(chuàng)建失敗
                {
                    CString strError;
                    strError.Format(
            "Create Socket Error Code : %d",GetLastError());//獲取錯誤代碼
                    return false;
                }

            }


            //啟動Socket線程
            BOOL CSocketComm::WatchServerSocket()
            {
                
            //首先判斷線程是否啟動
                if(!IsStart())
                
            {
                    
            //判斷是否打開通信,即socket是否成功創(chuàng)建
                    if(IsOpen())
                    
            {
                        HANDLE hThread;
                        UINT uiThreadId 
            = 0;
                        
            //啟動線程,使用_beginthreadex
                        hThread = (HANDLE)_beginthreadex(NULL,    // 安全參數(shù)
                                                            0,    // 堆棧
                                            SocketServerThreadProc,    // 線程程序
                                                        this,    // 線程參數(shù)
                                            CREATE_SUSPENDED,    //創(chuàng)建模式
                                                &uiThreadId);    // 線程ID
                        
            //如果線程不為空
                        if(hThread != NULL)
                        
            {
                            
            //繼續(xù)線程
                            ::ResumeThread(hThread);
                            m_hThread 
            = hThread;
                            
            return TRUE;
                        }

                    }

                }

                
            return false;
            }


            //服務(wù)端線程
            UINT WINAPI CSocketComm::SocketServerThreadProc(LPVOID pParam)
            {
                
            //reinterpret_cast用于各種指針的轉(zhuǎn)化
                CSocketComm* pThis = reinterpret_cast<CSocketComm*>(pParam);
                _ASSERTE( pThis 
            != NULL );

                pThis
            ->ServerRun();

                
            return 1L;
            }


            //Server主線程函數(shù),WaitForConnection()實(shí)際引用;
            void CSocketComm::ServerRun()
            {
                BYTE buffer[BUFFER_SIZE];
                DWORD dwBytes 
            = 0L;

                HANDLE hThread 
            = ::GetCurrentThread();
                DWORD dwTimeout 
            = DEFAULT_TIMEOUT;

                
            struct sockaddr_in ClientSockAddr; 
                
            int addrlen = sizeof(ClientSockAddr); 
                
                
            //int FAR* addrlen       
                
            //是否廣播模式
                if(!IsBroadCast())
                
            {
                    SOCKET sock 
            = (SOCKET) m_hSocket;
                    sock 
            = WaitForConnection(sock,(struct sockaddr *)&ClientSockAddr,&addrlen);//accept()
                    
            //等待新的連接
                    if(sock != INVALID_SOCKET)
                    
            {
                        
            //關(guān)閉連接
                        ShutDownConnection((SOCKET)m_hSocket);    //closesocket()
                        m_hSocket = (HANDLE) sock;
                        OnEvent(EVT_CONSUCCESS,ClientSockAddr);
            //connect
                    }

                    
            else
                    
            {
                        
            //如果已經(jīng)關(guān)閉則不發(fā)送事件,否則發(fā)送
                        if(IsOpen())
                            OnEvent(EVT_CONFAILURE,ClientSockAddr);
            //等待失敗
                        return;
                    }

                }

                
            //如果SOCKET 已經(jīng)創(chuàng)建
                while(IsOpen())
                
            {
                    
            //采用阻塞式SOCKET,等待事件通知
                    dwBytes = ReadComm(buffer,sizeof(buffer),dwTimeout);//recvfrom() or recv()
                    
            // 如果有錯誤發(fā)生
                    if (dwBytes == (DWORD)-1)
                    
            {
                        
            // 如果要關(guān)閉,則不發(fā)送事件
                        if (IsOpen())
                            OnEvent( EVT_CONDROP,ClientSockAddr ); 
            // 失去連接
                        break;
                    }

                    
            // 是否有數(shù)據(jù)收到
                    if (IsSmartAddressing() && dwBytes == sizeof(SOCKADDR_IN))
                        OnEvent( EVT_ZEROLENGTH ,ClientSockAddr);
                    
            else if (dwBytes > 0L)
                    
            {
                        OnDataReceived(buffer, dwBytes);
                    }

                    Sleep(
            0);
                }

            }


            //讀數(shù)據(jù)函數(shù)select();recvfrom();recv()
            DWORD CSocketComm::ReadComm(LPBYTE lpBuffer, DWORD dwSize, DWORD dwTimeout)
            {
                _ASSERTE(IsOpen());
                _ASSERTE(lpBuffer 
            != NULL);
                
            if(lpBuffer == NULL || dwSize<1L)
                    
            return 0L;

                fd_set fdRead 
            = {0};
                TIMEVAL stTime;
                TIMEVAL 
            *pstTime = NULL;

                
            if(INFINITE != dwTimeout)
                
            {
                    stTime.tv_sec
            =0;
                    stTime.tv_usec
            =dwTimeout*1000;
                    pstTime 
            = &stTime;
                }

                SOCKET s
            =(SOCKET)m_hSocket;
                
            //設(shè)定描述符
                if(!FD_ISSET(s,&fdRead))
                    FD_SET(s,
            &fdRead);

                
            //選擇函數(shù),設(shè)定超時(shí)時(shí)間
                DWORD dwBytesRead = 0L;
                
            int res = select(s+1,&fdRead,NULL,NULL,pstTime);
                
            if(res > 0)
                
            {
                    
            if(IsBroadCast() || IsSmartAddressing())
                    
            {
                        SOCKADDR_IN sockAddr 
            = {0};//獲得地址
                        int nOffset = IsSmartAddressing()?sizeof(sockAddr):0;
                        
            int nLen = sizeof(sockAddr);
                        
            if(dwSize < (DWORD)nLen)//緩沖區(qū)太小
                        {
                            ::SetLastError(ERROR_INVALID_USER_BUFFER);
                            
            return -1L;
                        }

                        
            //獲得數(shù)據(jù)
                        res = ::recvfrom(s,(LPSTR)&lpBuffer[nOffset],dwSize,0,(LPSOCKADDR)&sockAddr,&nLen);
                        
                        memset(
            &sockAddr.sin_addr,0,sizeof(sockAddr.sin_zero));
                        
            if(res>=0)
                        
            {
                            LockList();
            //鎖定地址列表
                            
            //刪除調(diào)重復(fù)地址
                            SockAddrIn sockin;
                            sockin.SetAddr(
            &sockAddr);
                            m_AddrList.remove(sockin);
                            m_AddrList.insert(m_AddrList.end(),sockin);

                            
            if(IsSmartAddressing())
                            
            {
                                memcpy(lpBuffer,
            &sockAddr,sizeof(sockAddr));
                                res
            +=sizeof(sockAddr);
                            }

                            UnlockList();
            //解開地址列表
                        }

                    }

                    
            else
                    
            {
                        res 
            = recv(s,(LPSTR)lpBuffer,dwSize,0);
                    }

                    dwBytesRead 
            = (DWORD)((res>0)?(res):(-1));
                }

                
                 
            return dwBytesRead;
            }

            posted on 2008-05-02 10:06 isabc 閱讀(717) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            廣告信息(免費(fèi)廣告聯(lián)系)

            中文版MSDN:
            歡迎體驗(yàn)

            国产精品VIDEOSSEX久久发布| 亚洲精品乱码久久久久久蜜桃不卡| 免费观看久久精彩视频| 久久黄色视频| 婷婷久久香蕉五月综合加勒比| 国产精品久久永久免费| 久久中文字幕无码专区| 亚洲午夜福利精品久久| 热re99久久精品国产99热| 日韩精品久久久久久久电影| 欧美伊香蕉久久综合类网站| 亚洲国产精品无码久久青草| 99re久久精品国产首页2020| 久久精品人人做人人爽电影| 久久黄色视频| 91久久精品视频| 久久久免费精品re6| 国产成年无码久久久免费| 精品久久国产一区二区三区香蕉| 日日躁夜夜躁狠狠久久AV| 久久91这里精品国产2020| 久久久亚洲欧洲日产国码aⅴ | 久久大香香蕉国产| 婷婷久久综合九色综合九七| 国产高潮国产高潮久久久91 | 97精品伊人久久久大香线蕉| 99久久成人18免费网站| 狠狠88综合久久久久综合网| 久久久久久伊人高潮影院 | 九九精品99久久久香蕉| yy6080久久| 久久久久久伊人高潮影院| 欧美成人免费观看久久| 中文字幕无码久久久| 2021国产精品午夜久久| 国产成人综合久久精品红| 精品国产乱码久久久久久人妻| 欧美一区二区久久精品| 亚洲成色www久久网站夜月| 久久久久人妻精品一区二区三区 | 久久精品水蜜桃av综合天堂|