Example #1
0
/*********************************************************
函数名称:OpenServer
功能描述:初始化服务器
作者:    余志荣
创建日期:2016-08-03
返 回 值:成功返回IDS_SERVER_OPEN_SUCCESS
*********************************************************/
int CSocketServerDlg::OpenServer(void)
{
	m_pSocketListen = new CListenSocket(this);

	if(!AfxSocketInit())
	{// 套接字初始化失败		
		OutputInfo(IDP_SOCKETS_INIT_FAILED); // 输出信息
		delete m_pSocketListen; // 清除Socket
		m_pSocketListen = NULL; // 指针置空
		return IDP_SOCKETS_INIT_FAILED;
	}

	if(m_pSocketListen->Create(8080) == NULL) 
	{// 绑定端口失败
		OutputInfo(IDP_SOCKETS_BIND_FAILED); // 输出信息
		delete m_pSocketListen; //清除Socket
		m_pSocketListen = NULL;
		return IDP_SOCKETS_BIND_FAILED;
	}
	
	m_pSocketListen->Listen(); //启动监听

	SetTimer(123, 10000, NULL); // 定时刷新Socket

	OutputInfo(IDS_SERVER_OPEN_SUCCESS); // 输出信息

	return IDS_SERVER_OPEN_SUCCESS;
}
Example #2
0
/*********************************************************
函数名称:CheckSocketStatus
功能描述:检查每个Socket 将其中空的和超时的删除掉
创建时间:2016-08-19
参数说明:
返 回 值:
*********************************************************/
int CSocketServerDlg::CheckSocketStatus(void)
{
	POSITION pos = m_listSocketChat.GetHeadPosition();
	while(pos != NULL)
	{
		CChatSocket* p = m_listSocketChat.GetNext(pos);
		// 删除空Socket
		if(p == NULL)
		{
			if(pos == NULL)
			{// 空Socket位于链表末尾
				m_listSocketChat.RemoveTail();
				break;
			}
			else
			{
				POSITION posTemp = pos;
				m_listSocketChat.GetPrev(posTemp);
				m_listSocketChat.RemoveAt(posTemp);
			}
			continue;
		}
		
		// 删除超过时间没有通信的Socket
		int nMaxSec = 30; // 等待的最大时间
		CTimeSpan tmsp;
		tmsp = CTime::GetCurrentTime() - p->m_tmLastMsg;
		TRACE("%d\n", tmsp.GetTotalSeconds());
		
		if(tmsp.GetTotalSeconds() >= nMaxSec || tmsp.GetSeconds() < 0)
		{
			CString csOutMsg;
			CString csID;
			csID = p->m_userID;
			csOutMsg.Format(_T("用户%s连接超时"), csID);
			OutputInfo(csOutMsg);
			
			m_data.SetUserStatus(p->m_userID, IDS_STATUS_OFFLINE);
			
			p->Close(); // 关闭连接
			delete p; // 释放内存
			// 删除元素
			if(pos == NULL)
			{// 空Socket位于链表末尾				
				m_listSocketChat.RemoveTail();
				break;
			}
			else
			{
				POSITION posTemp = pos;
				m_listSocketChat.GetPrev(posTemp);
				m_listSocketChat.RemoveAt(posTemp);
			}
			continue;
		}
	}
	return 0;
}
// this is FormatMatchesCapabilities for Audio
CodecSpecifier* PV2WayMIO::FormatMatchesCapabilities(const PVAsyncInformationalEvent& aEvent)
{
    PVMFFormatType aMimeString;
    int aMedia_Type = 0;
    ParseResponse(aEvent, aMimeString, aMedia_Type);
    // compare to what in iFormats instead.
    CodecSpecifier* formatInList = FormatInList(aMimeString);
    if (!formatInList)
    {
        OutputInfo("Format %s does not match application capability\n", aMimeString.getMIMEStrPtr());
    }
    else
    {
        OutputInfo("Format %s matches application capabilities\n", aMimeString.getMIMEStrPtr());
    }

    return formatInList;
}
OSCL_EXPORT_REF PVCommandId PV2WayMIO::Add()
{

    if (iMioNode == 0)
        return -1;
    int32 error = 0;
    if (!iAdded)
    {
        /*!

          Step 11: Add MIO Node to terminal
          Add appropriate MIO Node to terminal (audio/video, incoming/outgoing)
        */
        if (iMyDir == INCOMING)
        {
            OSCL_TRY(error, iAddId = iTerminal->AddDataSink(iChannelId,
                                     *iMioNode));
            if (error)
            {
                OutputInfo("PV2WayMIO::Add():: Error Adding Data Sink!");
            }
            return iAddId;
        }
        else
        {
            OSCL_TRY(error, iAddId = iTerminal->AddDataSource(iChannelId,
                                     *iMioNode));
            if (error)
            {
                OutputInfo("PV2WayMIO::Add():: Error Adding Data Source!");
            }
            return iAddId;
        }
    }
    else if (!iRemoving)
    {
        OutputInfo("\nError: MIO already added!\n");
    }
    else if (iRemoving)
    {
        OutputInfo("\nCannot add because attempting to remove MIO!\n");
    }
    return -1;
}
OSCL_EXPORT_REF void PV2WayMIO::PrintFormatTypes()
{
    Oscl_Map < PVMFFormatType, CodecSpecifier*,
    OsclMemAllocator, pvmf_format_type_key_compare_class >::iterator it =
        iFormatsMap.begin();
    if (it == iFormatsMap.end())
    {
        OutputInfo("No formats added.");
        return;
    }
    // loop through each, output values
    while (it != iFormatsMap.end())
    {
        CodecSpecifier* codec = (*it++).second;
        PVMFFormatType format = codec->GetFormat();
        OutputInfo("%s", format.getMIMEStrPtr());
        OutputInfo(" ");
    }
}
OSCL_EXPORT_REF PVCommandId PV2WayMIO::HandleEvent(const PVAsyncInformationalEvent& aEvent)
{
    PVCommandId retvalue = -1;
    TPVChannelId id = GetIdFromLocalBuffer((PVAsyncInformationalEvent &) aEvent);
    if (PVT_INDICATION_INCOMING_TRACK == aEvent.GetEventType())
    {
        if (((PVAsyncInformationalEvent&)aEvent).GetLocalBuffer()[0] == PV_VIDEO)
        {
            OutputInfo("PVT_INDICATION_INCOMING_TRACK video, id %d\n", id);
        }
        else if (((PVAsyncInformationalEvent&)aEvent).GetLocalBuffer()[0] == PV_AUDIO)
        {
            OutputInfo("PVT_INDICATION_INCOMING_TRACK audio, id %d\n", id);
        }
    }
    else if (PVT_INDICATION_OUTGOING_TRACK == aEvent.GetEventType())
    {
        if (((PVAsyncInformationalEvent&)aEvent).GetLocalBuffer()[0] == PV_VIDEO)
        {
            OutputInfo("PVT_INDICATION_OUTGOING_TRACK video, id %d\n", id);
        }
        else if (((PVAsyncInformationalEvent&)aEvent).GetLocalBuffer()[0] == PV_AUDIO)
        {
            OutputInfo("PVT_INDICATION_OUTGOING_TRACK audio, id %d\n", id);
        }
    }
    if (iChannelId == id)
    {
        OutputInfo("\nDuplicate callback for  id %d\n", id);
        return -1;
    }

    if (iChannelId)
    {
        OutputInfo("\nBusy ... MIO id=%d being closed\n", iChannelId);
        iNextChannelId = id;
        return -1;
    }
    if (!iClosing && !iAdded)
    {
        iChannelId = id;
        // format matching capabilities and create- create can tell us which kind to create
        // including which file we should use, etc.
        iSelectedCodec = FormatMatchesCapabilities(aEvent);
        if (iSelectedCodec)
        {
            iMioNode = iObserver->CreateMIONode(iSelectedCodec, iMyDir);
            iMySelectedFormat = iSelectedCodec->GetFormat();
            retvalue = Add();
        }
        else
        {
            OutputInfo("\nDid not find a codec!!! \n");
        }
    }
    return retvalue;
}
OSCL_EXPORT_REF void PV2WayMIO::AddCompleted(const PVCmdResponse& aResponse)
{
    if (aResponse.GetCmdStatus() == PVMFSuccess)
    {
        iAdded = true;
    }
    else
    {
        OutputInfo("PV2WayMIO::AddCompleted:: Failed to add MIO");
        Closed();
    }

    iAddId = -1;
}
OSCL_EXPORT_REF int PV2WayDummySourceAndSinks::AddPreferredCodec(TPVDirection aDir,
        PV2WayMediaType aMediaType,
        LipSyncDummyMIOSettings& aSettings)
{
    PV2WayMIO* mio = GetMIO(aDir, aMediaType);
    if (mio)

    {
        mio->AddCodec(aSettings);
        return 0;
    }
    OutputInfo("PV2WaySourceAndSinksBase::AddPreferredCodec: Error!  No MIO of given dir, type");
    return -1;
}
OSCL_EXPORT_REF PVCommandId PV2WayMIO::Remove()
{
    int32 error = 0;
    iRemoving = true;
    /*!

      Step 12: Cleanup
      Step 12a: Remove source and sinks
    */
    if (iMioNode && iRemoveId == -1)
    {
        if (iMyDir == INCOMING)
        {
            OSCL_TRY(error, iRemoveId = iTerminal->RemoveDataSink(*iMioNode));
            if (error)
            {
                OutputInfo("\n Error in RemoveDataSink!\n");
            }
            return iRemoveId;
        }
        else
        {
            OSCL_TRY(error, iRemoveId = iTerminal->RemoveDataSource(*iMioNode));
            if (error)
            {
                OutputInfo("\n Error in RemoveDataSource!\n");
            }
            return iRemoveId;
        }
    }
    else if (!iAdded)
    {
        OutputInfo("\nError: MIO cannot be removed because has not been added!\n");
    }
    return -1;
}
Example #10
0
/*********************************************************
函数名称:Register
功能描述:用户注册
参数说明:msg-消息结构体 pSocket-接收到消息的pSocket
返 回 值:
*********************************************************/
int CSocketServerDlg::Register(struct MSG_REGISTER * msg_reg, CChatSocket * pSocket)
{
	char nID[ID_MAX];
	m_data.AddUser(nID, msg_reg);

	msg_reg->nType = REGISTER_SUCCESS;
	strcpy_s(msg_reg->nID, nID);
	if(pSocket->Send(msg_reg, sizeof(*msg_reg)) == 0)
	{// 发送失败
		OutputInfo(IDS_ERR_SOCKETS_SEND_FAILED);
		return IDS_ERR_SOCKETS_SEND_FAILED;
	}
	delete msg_reg; // 释放内存
	RefreshListCtrlData();
	return 0;
}
Example #11
0
/*********************************************************
函数名称:LoginOut
功能描述:用户下线
作者:    余志荣
创建日期:2016-08-03
参数说明:msg-消息结构体 pSocket-接收到消息的pSocket
返 回 值:
*********************************************************/
int CSocketServerDlg::LoginOut(struct MSG_LOGIN * msg, CChatSocket * pSocket)
{
	// 将状态设置为离线
	m_data.SetUserStatus(pSocket->m_userID, IDS_STATUS_OFFLINE);

	CString csOutMsg;
	CString csID;
	csID = msg->nID;
	csOutMsg.Format(_T("用户%s已退出"), csID);
	OutputInfo(csOutMsg);
	// 删除文件socket列表中的指针
	POSITION pos = m_FileSocketList.GetHeadPosition();
	while (pos != NULL)
	{
		CChatSocket *p =m_FileSocketList.GetAt(pos);
		if(!strcmp(pSocket->m_userID, p->m_userID))
		{
			p->Close();
			delete p;
			m_FileSocketList.RemoveAt(pos);
			break;
		}
		m_FileSocketList.GetNext(pos);
	}
	// 删除聊天socket列表中的指针
	pos = m_listSocketChat.GetHeadPosition();
	while(pos != NULL)
	{
		CChatSocket * p = m_listSocketChat.GetAt(pos);
		if(pSocket == p)
		{
			pSocket->Close();
			delete pSocket;
			m_listSocketChat.RemoveAt(pos);
			break;
		}
		m_listSocketChat.GetNext(pos);
	}

	// 刷新用户列表
	RefreshListCtrlData();
	return 0;
}
Example #12
0
/*********************************************************
函数名称:GetFriendInfo
功能描述:获得好友信息
参数说明:msg-消息结构体 pSocket-接收到消息的pSocket
返 回 值:
*********************************************************/
int CSocketServerDlg::GetFriendInfo(struct MSG_USERINFO * msg_userinfo, CChatSocket * pSocket)
{
	struct MSG_USERINFO info;	
	if(m_data.GetUserInfo(info, msg_userinfo->nID) != IDS_ERR_USER_NOT_EXIST)
	{
		info.nType = GET_FRIEND_INFO;
		if(pSocket->Send(&info, sizeof(info)) == 0)
		{//发送失败
			OutputInfo(IDS_ERR_SOCKETS_SEND_FAILED);
			return IDS_ERR_SOCKETS_SEND_FAILED;
		}
		
	}
	else
	{// 查询的用户不存在
		
	
	}
	return 0;
}
Example #13
0
/*********************************************************
函数名称:GetStrangerInfo
功能描述:获得陌生人信息
参数说明:msg-消息结构体 pSocket-接收到消息的pSocket
返 回 值:
*********************************************************/
int CSocketServerDlg::GetStrangerInfo(struct MSG_USERINFO * msg_userinfo, CChatSocket * pSocket)
{
	struct MSG_USERINFO info;
	if(m_data.GetUserPublicInfo(info, msg_userinfo->nID) != IDS_ERR_USER_NOT_EXIST)
	{
		info.nType = GET_STRANGER_INFO;	
		if(pSocket->Send(&info, sizeof(info)) == 0)
		{//发送失败
			OutputInfo(IDS_ERR_SOCKETS_SEND_FAILED);
			return IDS_ERR_SOCKETS_SEND_FAILED;
		}
	}
	else
	{// 查询的用户不存在
		struct MSG_SYS msg_sys;
		msg_sys.nType = IDS_SYSTEM_MESSAGE;
		msg_sys.nIDPrompt = IDS_ERR_USER_NOT_EXIST;
		pSocket->Send(&msg_sys, sizeof(msg_sys));
	}
	return 0;
}
Example #14
0
/*********************************************************
函数名称:Login
功能描述:用户登录
作者:    余志荣
创建日期:2016-08-03
参数说明:msg-消息结构体 pSocket-接收到消息的pSocket
返 回 值:
*********************************************************/
int CSocketServerDlg::Login(struct MSG_LOGIN * msg, CChatSocket * pSocket)
{
	int nRes = m_data.IsCorrect(msg->nID, msg->Key);

	if(nRes == TRUE)// 检查账号密码正确性
	{// 密码正确
		if(m_data.GetUserStatus(msg->nID) == IDS_STATUS_OFFLINE)
		{// 允许登录
			// 给客户端返回账号信息
			struct MSG_USERINFO msg_info;
			msg_info.nType = LOGIN_SUCCESS;
			m_data.GetUserInfo(msg_info, msg->nID);
			if(pSocket->Send((void *)&msg_info, sizeof(msg_info)) == 0)
			{//发送失败
				OutputInfo(IDS_ERR_SOCKETS_SEND_FAILED);
				return IDS_ERR_SOCKETS_SEND_FAILED;
			}

			strcpy_s(pSocket->m_userID, msg->nID); // 设置pSocket的nID
			m_data.SetUserStatus(msg->nID, msg->nStatus);		
			RefreshListCtrlData(); // 更新列表控件中的数据
			
			// 在编辑框输出信息		
			CString csOutMsg;
			CString csID;
			csID = msg->nID;
			csOutMsg.Format(_T("用户%s已连接"), csID);
			OutputInfo(csOutMsg);
		}
		else
		{// 拒绝登录 原因:重复登录
			// 服务器返回信息 告诉客户端登录失败
			struct MSG_SYS msg_sys;
			msg_sys.nType = IDS_SYSTEM_MESSAGE;
			msg_sys.nIDPrompt = IDS_ERR_ID_HAD_LOGIN;
			if(pSocket->Send((void *)&msg_sys, sizeof(msg_sys)) == 0)
			{//发送失败
				OutputInfo(IDS_ERR_SOCKETS_SEND_FAILED);
				return IDS_ERR_SOCKETS_SEND_FAILED;
			}		
		}
	}
	else if(nRes == IDS_ERR_PASSWD_INCORRECT)
	{// 拒绝登陆 原因:密码错误
		// 服务器返回信息 告诉客户端登录失败
		struct MSG_SYS msg_sys;
		msg_sys.nType = IDS_SYSTEM_MESSAGE;
		msg_sys.nIDPrompt = IDS_ERR_PASSWD_INCORRECT;
		if(pSocket->Send((void *)&msg_sys, sizeof(msg_sys)) == 0)
		{//发送失败
			OutputInfo(IDS_ERR_SOCKETS_SEND_FAILED);				
			return IDS_ERR_SOCKETS_SEND_FAILED;
		}	
	}
	else if(nRes == IDS_ERR_USER_NOT_EXIST)
	{// 用户不存在
		struct MSG_SYS msg_sys;
		msg_sys.nType = IDS_SYSTEM_MESSAGE;
		msg_sys.nIDPrompt = IDS_ERR_USER_NOT_EXIST;
		pSocket->Send(&msg_sys, sizeof(msg_sys));
	}
	return TRUE;
}
Example #15
0
/*********************************************************
函数名称:RecvMsg
功能描述:接收信息
作者:    余志荣
创建日期:2016-08-03
参数说明:pSocket -- 接收到消息的pSocket
返 回 值:接收到的字节数
*********************************************************/
int CSocketServerDlg::RecvMsg(CChatSocket * pSocket)
{
	int iBufSize = MSG_SIZE_MAX; // 接收的最大字节数
	struct MSG_T *msg = new struct MSG_T;
	int iRes = pSocket->Receive((char *)msg, iBufSize);	
	if(iRes == SOCKET_ERROR) // 接收失败
	{
		//MessageBox(_T("SOCKET_ERROR"));
		OutputInfo(_T("SOCKET_ERROR"));
		return 0;
	}
	
	switch(msg->nType)
	{
	// 登陆/下线
	case LOGIN: // 登录消息
		Login((struct MSG_LOGIN *)msg, pSocket);
		break;
	case LOGIN_OUT: // 下线消息
		LoginOut((struct MSG_LOGIN *)msg, pSocket);
		break;
	case GET_FRIEND_LIST: // 请求获得好友列表
		GetFriendList((struct MSG_USERINFO *)msg, pSocket);break;
	case GET_ALL_FRIEND_INFO: // 请求获得全部好友的基本信息
		GetAllFriendInfo((struct MSG_FRND_INFO*)msg, pSocket);break;
	case SET_USER_STATUS: // 设置在线状态
		SetUserStatus((struct MSG_USERINFO *)msg, pSocket);break;
	
	// 注册
	case REGISTER: // 注册消息
		Register((struct MSG_REGISTER *)msg, pSocket);
		break;

	// 一对一聊天
	case GET_FRIEND_INFO: // 请求获得好友信息
		GetFriendInfo((struct MSG_USERINFO *)msg, pSocket);break;
	case CHATING_TEXT_MSG: // 聊天消息
		RelayChatMsg((struct MSG_TRANSPOND *)msg, pSocket);break;
	
	// 增删好友
	case ADD_FRIEND_REQUEST: // 添加好友请求
		RelayChatMsg((struct MSG_TRANSPOND *)msg, pSocket);break;
	case ADD_FRIEND_ANSWER: // 添加请求回应
		AddFriend((struct MSG_TRANSPOND *)msg, pSocket);break;
	case DELETE_FRIEND: // 删除好友
		DeleteFriend((MSG_MAKE_FRIEND *)msg, pSocket);break;
	case GET_STRANGER_INFO: // 请求获得陌生人信息
		GetStrangerInfo((struct MSG_USERINFO *)msg, pSocket);break;

	
	// 心跳包
	case HEARTBEAT:
		pSocket->Send(msg, sizeof(MSG_SYS));
		//TRACE(pSocket->m_userID);
		//TRACE("\n");
		break;
	
	// 文件传输
	case MESSAGE_FILE_REQUEST: // 发送请求
		FileTransRequest((MSG_FILE_REQUEST*)msg);
		break;
	case MESSAGE_FILE_AGREE: // 同意发送
	case MESSAGE_FILE_REFUSE: // 拒绝发送
	case MESSAGE_FILE_ERROR: // 出现错误
		FileTransAnswer((MSG_FILE_REQUEST*)msg);
		break;
	case FILE_TRANS_SOCKET:
		strcpy_s(pSocket->m_userID, ((MSG_SYS*)msg)->nID);
		AddToFileSocketList(pSocket);
		break;
	case MESSAGE_FILE_TRANS_BEGIN:
	case MESSAGE_FILE_TRANS_END:
		FileTransOpera((MSG_FILE_OPERA *)msg, pSocket);
		//FileTransRelay((MSG_FILE_REQUEST*)msg);// (未使用)
		break;
	case MESSAGE_FILE_CONTENT:
		FileTransRelay((MSG_FILE_CONTENT*)msg);
		break;



	default:
		//MessageBox(L"未定义的数据类型!");

		break;
	}
	return iRes;
}
Example #16
0
/*********************************************************
函数名称:CloseServer
功能描述:关闭服务器
作者:    余志荣
创建日期:2016-09-01
返 回 值:成功返回TRUE
*********************************************************/
int CSocketServerDlg::CloseServer(void)
{
	// 断开所有客户端的连接
	POSITION pos = m_listSocketChat.GetHeadPosition();
	POSITION posTemp;
	while (pos != NULL)
	{
		CChatSocket *pSocket = m_listSocketChat.GetNext(pos);
		pSocket->Close();
		delete pSocket;
		posTemp = pos;
		if(posTemp == NULL)
		{
			m_listSocketChat.RemoveTail();
		}
		else
		{
			m_listSocketChat.GetPrev(posTemp);
			m_listSocketChat.RemoveAt(posTemp);
		}
		/*
		CChatSocket *pSocket = m_listSocketChat.GetAt(pos);
		pSocket->Close();
		delete pSocket;
		//m_listSocketChat.RemoveAt(pos);
		m_listSocketChat.GetNext(pos);
		*/
	}
	pos = m_FileSocketList.GetHeadPosition();
	while (pos != NULL)
	{
		CChatSocket *pSocket = m_FileSocketList.GetNext(pos);
		pSocket->Close();
		delete pSocket;
		posTemp = pos;
		if (pos == NULL)
		{
			m_FileSocketList.RemoveTail();
		} 
		else
		{
			m_FileSocketList.GetPrev(posTemp);
			m_FileSocketList.RemoveAt(posTemp);
		}
		/*
		CChatSocket *pSocket = m_FileSocketList.GetAt(pos);
		pSocket->Close();
		delete pSocket;
		//m_FileSocketList.RemoveAt(pos);
		m_FileSocketList.GetNext(pos);
		*/
	}

	// 关闭监听
	m_pSocketListen->Close();
	delete m_pSocketListen;
	m_pSocketListen = NULL;

	OutputInfo(L"关闭服务成功。");
	return TRUE;
}