1. 問下MFC是如何實現語音聊天的。
語音聊天就要用到麥克風的聲音捕獲了,一般用的directsound或是directmusic,你可以搜一下相關的資料,捕獲聲音後,通過網路傳輸到另一客戶端,然後播放出來, 這中間又用到socket編程 ,具體的請 到網上找相關資料,這些不是三兩句話能說完的。
2. 有誰用過MFC編寫過聊天工具,,區域網聊天工具網上有,問題是MFC能實現廣域網聊天功能嗎
看你的聊天工具是點對點還是只是與伺服器通訊,伺服器負責轉發到其他指定的用戶那裡
這樣的話,都差不多
用戶,有獨立網際網路IP的,有區域網內網的,隨便
用戶的MFC聊天工具定時連接伺服器檢查有沒有自己的信息,有就取過來顯示
自己要發送信息,就連接伺服器,把信息塞給伺服器,告知發給哪位用戶
完了
如果是點對點的,首先就是要知道對方的IP,區域網可以掃描,如果固定監聽某個或某幾個/某段埠的話,但是廣域網必須有一個固定的伺服器,直接有網際網路IP的伺服器
大家都去連接這個伺服器,通過與伺服器通信,查詢在線人列表,IP,埠,擁有網際網路IP地址的用戶就可以直接連接對方的IP埠,要連接到內網的用戶,就需要利用UDP協議來打洞,打洞好了的話,你就可以直接連接對方,而不需要通過伺服器中轉了
即使兩個都是內網的用戶聊天,打好洞,也就是路由器NAT做了埠映射,這兩個內網用戶就可以點對點直連了
3. 如何用標准C++寫個聊天室程序
因為設計到消息的傳送,必須使用socket編程
我目前知道兩種方法 分別是winsock和ace_sock 就是windows的和ACE框架下
如果想實現聊天室不用MFC的話就需要自己手動生成界面 很難實現
下面分別給出windows和ace的關鍵代碼 可以參考一下
//-----------------------------------
// ACE 部分
//----------------------------------
ACE::init();
ACE_INET_Addr DestAddr(8090, "192.168.208.24");
ACE_SOCK_Connector connector;
ACE_SOCK_Stream peer ;
if(-1 == connector.connect(peer,DestAddr))
{
MessageBox("連接失敗!");
}
ssize_t SendSize = peer.send_n("hello world\n",11);
peer.close();
ACE::fini();
}
//-----------------------------------
// Winsock 部分
//----------------------------------
WSADATA wsaData ;
int SrcAddr;
int err = WSAStartup(MAKEWORD(2,1),&wsaData);
if (err != 0) return;
struct sockaddr_in DestAddr;
memset(&DestAddr , 0 , sizeof(DestAddr));
DestAddr.sin_family = AF_INET;
DestAddr.sin_addr.s_addr = inet_addr("192.168.208.24");
DestAddr.sin_port = htons(8090);
SrcAddr = socket(AF_INET,SOCK_STREAM ,0);
int succ ;
if(connect(SrcAddr,(struct sockaddr *)&DestAddr,sizeof(DestAddr)) == 0)
{
succ = send(SrcAddr,"hello world",11,0);
}
shutdown(SrcAddr,2);
closesocket(SrcAddr);
WSACleanup();
}
我說的不夠明白么 可以但是就用你現在學的東西不行 譚浩強的書太基礎了
4. 如何利用MFC編寫一個類似於QQ的聊天軟體
要實現一個伺服器一個客戶端的聊天很簡單,用UDP,知道IP埠就好辦。我覺得要實現像QQ一樣的聊天軟體難點在1、外網通信,要NAT穿透什麼的。。。兩個路由器後面的IP就很難連接 2、多用戶同時參與聊天時候後台的邏輯設計。。
可能說的不對,不過這是我當時想實現這類聊天軟體功能時遇到的最大問題。
僅供交流= =
5. 用C語言實現語音聊天的mfc程序
世界本來就是一部分面向過程,一部分面向對象的,有些東西非要硬把他全面向對象,MFC就是這么個變態......
mfc裡面都是封裝好的類,算是C++了,你怎麼用C寫MFC程序?
C有C的C運行時庫,WINDOWS下的C也可以直接用WINDOWS標准庫(WindowsApi)
關於Windows音頻開發的相關,可以參考《Windows程序設計》第二部分,第22章,裡面有詳細介紹音頻的原理和如何從設備讀入音頻,如何向設備輸出音頻
6. vc++6.0編的基於MFC的簡單的tcp聊天程序
4.1伺服器端代碼
開啟伺服器功能:
void OnServerOpen() //開啟伺服器功能
{
WSADATA wsaData;
int iErrorCode;
char chInfo[64];
if (WSAStartup(WINSOCK_VERSION, &wsaData)) //調用Windows Sockets DLL
{ MessageBeep(MB_ICONSTOP);
MessageBox("Winsock無法初始化!", AfxGetAppName(), MB_OK|MB_ICONSTOP);
WSACleanup();
return; }
else
WSACleanup();
if (gethostname(chInfo, sizeof(chInfo)))
{ ReportWinsockErr("\n無法獲取主機!\n ");
return; }
CString csWinsockID = "\n==>>伺服器功能開啟在埠:No. ";
csWinsockID += itoa(m_pDoc->m_nServerPort, chInfo, 10);
csWinsockID += "\n";
PrintString(csWinsockID); //在程序視圖顯示提示信息的函數,讀者可自行創建
m_pDoc->m_hServerSocket=socket(PF_INET, SOCK_STREAM, DEFAULT_PROTOCOL);
//創建伺服器端Socket,類型為SOCK_STREAM,面向連接的通信
if (m_pDoc->m_hServerSocket == INVALID_SOCKET)
{ ReportWinsockErr("無法創建伺服器socket!");
return;}
m_pDoc->m_sockServerAddr.sin_family = AF_INET;
m_pDoc->m_sockServerAddr.sin_addr.s_addr = INADDR_ANY;
m_pDoc->m_sockServerAddr.sin_port = htons(m_pDoc->m_nServerPort);
if (bind(m_pDoc->m_hServerSocket, (LPSOCKADDR)&m_pDoc->m_sockServerAddr,
sizeof(m_pDoc->m_sockServerAddr)) == SOCKET_ERROR) //與選定的埠綁定
{ReportWinsockErr("無法綁定伺服器socket!");
return;}
iErrorCode=WSAAsyncSelect(m_pDoc->m_hServerSocket,m_hWnd,
WM_SERVER_ACCEPT, FD_ACCEPT);
//設定伺服器相應的網路事件為FD_ACCEPT,即連接請求,
// 產生相應傳遞給窗口的消息為WM_SERVER_ACCEPT
if (iErrorCode == SOCKET_ERROR)
{ ReportWinsockErr("WSAAsyncSelect設定失敗!");
return;}
if (listen(m_pDoc->m_hServerSocket, QUEUE_SIZE) == SOCKET_ERROR) //開始監聽客戶連接請求
{ReportWinsockErr("伺服器socket監聽失敗!");
m_pParentMenu->EnableMenuItem(ID_SERVER_OPEN, MF_ENABLED);
return;}
m_bServerIsOpen = TRUE; //監視伺服器是否打開的變數
return;
}
響應客戶發送聊天文字到伺服器:ON_MESSAGE(WM_CLIENT_READ, OnClientRead)
LRESULT OnClientRead(WPARAM wParam, LPARAM lParam)
{
int iRead;
int iBufferLength;
int iEnd;
int iRemainSpace;
char chInBuffer[1024];
int i;
for(i=0;(i
//MAXClient是伺服器可響應連接的最大數目
{}
if(i==MAXClient) return 0L;
iBufferLength = iRemainSpace = sizeof(chInBuffer);
iEnd = 0;
iRemainSpace -= iEnd;
iBytesRead = recv(m_aClientSocket[i], (LPSTR)(chInBuffer+iEnd), iSpaceRemaining, NO_FLAGS);
//用可控緩沖接收函數recv()來接收字元
iEnd+=iRead;
if (iBytesRead == SOCKET_ERROR)
ReportWinsockErr("recv出錯!");
chInBuffer[iEnd] = '\0';
if (lstrlen(chInBuffer) != 0)
{PrintString(chInBuffer); //伺服器端文字顯示
OnServerBroadcast(chInBuffer); //自己編寫的函數,向所有連接的客戶廣播這個客戶的聊天文字
}
return(0L);
}
對於客戶斷開連接,會產生一個FD_CLOSE消息,只須相應地用closesocket()關閉相應的Socket即可,這個處理比較簡單。
4.2客戶端代碼
連接到伺服器:
void OnSocketConnect()
{ WSADATA wsaData;
DWORD dwIPAddr;
SOCKADDR_IN sockAddr;
if(WSAStartup(WINSOCK_VERSION,&wsaData)) //調用Windows Sockets DLL
{MessageBox("Winsock無法初始化!",NULL,MB_OK);
return;
}
m_hSocket=socket(PF_INET,SOCK_STREAM,0); //創建面向連接的socket
sockAddr.sin_family=AF_INET; //使用TCP/IP協議
sockAddr.sin_port=m_iPort; //客戶端指定的IP地址
sockAddr.sin_addr.S_un.S_addr=dwIPAddr;
int nConnect=connect(m_hSocket,(LPSOCKADDR)&sockAddr,sizeof(sockAddr)); //請求連接
if(nConnect)
ReportWinsockErr("連接失敗!");
else
MessageBox("連接成功!",NULL,MB_OK);
int iErrorCode=WSAAsyncSelect(m_hSocket,m_hWnd,WM_SOCKET_READ,FD_READ);
//指定響應的事件,為伺服器發送來字元
if(iErrorCode==SOCKET_ERROR)
MessageBox("WSAAsyncSelect設定失敗!");
}
接收伺服器端發送的字元也使用可控緩沖接收函數recv(),客戶端聊天的字元發送使用數據可控緩沖發送函數send(),這兩個過程比較簡單,在此就不加贅述了。
7. 用MFC寫一個聊天工具 要用到哪些方面的知識
就這些:
16.聊天室伺服器端邏輯
一、伺服器端所聲明的類
class CCSocketDlg : public CDialog
{
// Construction
public:
CCSocketDlg(CWnd* pParent = NULL); // standard constructor
~CCSocketDlg();
// Dialog Data
//{{AFX_DATA(CCSocketDlg)
enum { IDD = IDD_CSOCKET_DIALOG };
CButton m_button;
CListCtrl m_list;
CEdit m_edit;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CCSocketDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CCSocketDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
virtual void OnOK();
afx_msg void OnButton1();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
public:
WSADATA wsaData;
SOCKET clisock;
SOCKET sListen, sAccept;
int addlen;
int count,s;
int getcount();
void sendtoall(SOCKET,char*);
struct sockaddr_in ser, cli; //伺服器和客戶的地址
int iLen; //客戶地址長度
int iSend;//發送的數據長度
int flag;//標志位
char buf[1000];//要發送給客戶的信息
void CRS();
};
UINT thread(LPVOID);
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CSOCKETDLG_H__2DFDFAF0_3473_43E6_A5CB_DBB8531B370E__INCLUDED_)
二、伺服器端
// CSocketDlg.cpp : implementation file
//伺服器端
#include "stdafx.h"
#include "CSocket.h"
#include "CSocketDlg.h"
#include <io.h>
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCSocketDlg dialog
CCSocketDlg::CCSocketDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCSocketDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CCSocketDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCSocketDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCSocketDlg)
DDX_Control(pDX, IDC_BUTTON1, m_button);
DDX_Control(pDX, IDC_LIST1, m_list);
DDX_Control(pDX, IDC_EDIT1, m_edit);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CCSocketDlg, CDialog)
//{{AFX_MSG_MAP(CCSocketDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CCSocketDlg message handlers
//初始化對話框
BOOL CCSocketDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
int count,s=1;
// char buff[100];
CDialog a;
CCSocketDlg *dlg=(CCSocketDlg*)AfxGetApp()->GetMainWnd();
count=0;
m_list.InsertColumn(0,"消息");
m_list.SetColumnWidth(0,435);
m_edit.SetLimitText(99);
dlg->sAccept=NULL;
//設定地址
dlg->ser.sin_addr.s_addr=htonl(INADDR_ANY);
dlg->ser.sin_family=AF_INET;
dlg->ser.sin_port=htons(5000);
addlen=sizeof(dlg->ser);
m_button.EnableWindow(FALSE);
//創建伺服器端的套介面
dlg->sListen=socket(AF_INET,SOCK_STREAM,0);
if (dlg->sListen==INVALID_SOCKET)
{
m_edit.SetWindowText("創建套介面失敗");
return FALSE;
}
//綁定
if (bind(dlg->sListen,(SOCKADDR*)&(dlg->ser),addlen))=SOCKET_ERROR)
{
closesocket(dlg->sListen);
m_edit.SetWindowText("綁定錯誤");
return FALSE;
}
else{
m_edit.SetWindowText("伺服器創建成功");
//開始偵聽
if (listen(dlg->sListen,5)==SOCKET_ERROR)
{
m_edit.SetWindowText("偵聽失敗");
return FALSE;
}
CRS();
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CCSocketDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CCSocketDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCSocketDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CCSocketDlg::OnOK()
{
// CDialog::OnOK();
}
//發送數據
void CCSocketDlg::OnButton1()
{
char buff[100];
m_edit.GetWindowText(buff,99);
m_edit.SetWindowText("");
m_list.InsertItem(count++,buff);
//m_list.Scroll(size);
if (sAccept!=NULL)
//發送
send(sAccept,buff,100,0);
}
CCSocketDlg::~CCSocketDlg()
{
if (sAccept!=NULL)
send(sAccept,"Disconnected",100,0);
}
void CCSocketDlg::CRS()
{
char buff[100];
CCSocketDlg *dlg=(CCSocketDlg*)AfxGetApp()->GetMainWnd();
//初始化客戶地址長度參數
iLen=sizeof(dlg->cli);
//進入一個無限循環,等待客戶的連接請求
while(1)
{
dlg->sAccept=accept(dlg->sListen,(sockaddr*)&(dlg->ser),&(dlg->iLen));
if (dlg->sAccept==INVALID_SOCKET)
{ dlg->m_edit.SetWindowText("Error accept");}
dlg->m_list.InsertItem(dlg->count++,"連接成功");
char *ctime( const time_t *timer );
time_t ltime;
time(<ime);
dlg->m_list.InsertItem(dlg->count++,ctime( <ime ) );
s=recv(dlg->sAccept,buff,100,0);
dlg->SetForegroundWindow();
if (s!=SOCKET_ERROR)
{
dlg->m_list.InsertItem(dlg->count++,buff);
dlg->m_list.InsertItem(dlg->count++,ctime( <ime ) );
if (dlg->sAccept!=NULL)
//發送
send(dlg->sAccept,buff,100,0);
//dlg->sendtoall(dlg->sAccept,buff);
closesocket(dlg->sAccept);
}
}//end While
closesocket(dlg->sListen);
WSACleanup();
}
8. MFC聊天室怎麼實現
分伺服器和客戶端,利用CSocket類(套接字),思想:首先伺服器端創建套接字,bind將套接字與本地IP綁定,然後監聽(listen)通知TCP伺服器准備鏈接請求,ACCEPT等待接收客戶端鏈接請求,send/read信息,關閉套接字。客戶端創建套接字,之後connect鏈接伺服器,send/read信息,close套接字。再結合MFC的控制項,這個程序不難。最好找些資料閱讀一下就行 了。
9. MFC中基於UDP編寫一個簡單的聊天室程序,其中在獲取對方IP地址時有這么一句:
GetDlgItem(IDC_IPADDRESS1))是獲取控制項ID為IDC_IPADDRESS1的句柄
這個是MFC里的IP控制項,調用GetAddress,取得IP地址,然後強轉成CIPAddressCtrl*指針類型。