• <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>

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

            Blog @ Blog

            當華美的葉片落盡,生命的脈絡才歷歷可見。 -- 聶魯達

            常用鏈接

            統計

            積分與排名

            BBS

            Blog

            Web

            最新評論

            啟動服務流程代碼

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

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

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

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

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

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

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

                SOCKADDR_IN sockAddr 
            = 0 };
                
            //地址設定 //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) //設定相關選項
                        {
                            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協議
                        {
                            
            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;// 設定變量
                            }

                            m_hMutex 
            = CreateMutex(NULL, FALSE, NULL);// 如果需要廣播,則需要設定進程互斥
                            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//創建失敗
                {
                    CString strError;
                    strError.Format(
            "Create Socket Error Code : %d",GetLastError());//獲取錯誤代碼
                    return false;
                }

            }


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

                    }

                }

                
            return false;
            }


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

                pThis
            ->ServerRun();

                
            return 1L;
            }


            //Server主線程函數,WaitForConnection()實際引用;
            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)
                    
            {
                        
            //關閉連接
                        ShutDownConnection((SOCKET)m_hSocket);    //closesocket()
                        m_hSocket = (HANDLE) sock;
                        OnEvent(EVT_CONSUCCESS,ClientSockAddr);
            //connect
                    }

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

                }

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

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

                    Sleep(
            0);
                }

            }


            //讀數據函數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;
                
            //設定描述符
                if(!FD_ISSET(s,&fdRead))
                    FD_SET(s,
            &fdRead);

                
            //選擇函數,設定超時時間
                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)//緩沖區太小
                        {
                            ::SetLastError(ERROR_INVALID_USER_BUFFER);
                            
            return -1L;
                        }

                        
            //獲得數據
                        res = ::recvfrom(s,(LPSTR)&lpBuffer[nOffset],dwSize,0,(LPSOCKADDR)&sockAddr,&nLen);
                        
                        memset(
            &sockAddr.sin_addr,0,sizeof(sockAddr.sin_zero));
                        
            if(res>=0)
                        
            {
                            LockList();
            //鎖定地址列表
                            
            //刪除調重復地址
                            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 閱讀(706) 評論(0)  編輯 收藏 引用

            廣告信息(免費廣告聯系)

            中文版MSDN:
            歡迎體驗

            中文成人无码精品久久久不卡| 中文字幕一区二区三区久久网站| 人妻无码久久精品| 国产精品一区二区久久精品涩爱 | 国产成人精品久久一区二区三区av | 中文精品久久久久人妻不卡| 久久ZYZ资源站无码中文动漫| 久久香蕉国产线看观看乱码| 久久久久久一区国产精品| 伊人久久精品无码二区麻豆| 久久美女网站免费| 国产精品乱码久久久久久软件| 色8久久人人97超碰香蕉987| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 亚洲国产天堂久久久久久| 久久99国产综合精品女同| 久久国产精品无码网站| 久久99国产综合精品女同| 伊人久久一区二区三区无码| 色成年激情久久综合| 日产精品99久久久久久| 午夜精品久久久久| 国产精品99久久久久久猫咪| 久久中文骚妇内射| 亚洲欧美成人综合久久久| 久久久中文字幕日本| 久久久精品一区二区三区| 欧洲成人午夜精品无码区久久 | 久久精品视频网| 久久久久亚洲Av无码专| 影音先锋女人AV鲁色资源网久久| 久久精品国产一区二区三区| 99久久免费国产精品热| 久久精品国产亚洲AV大全| 中文字幕无码免费久久| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 人妻精品久久无码专区精东影业| 久久久WWW成人| 久久综合成人网| 热RE99久久精品国产66热| 欧美精品一本久久男人的天堂|