SpeakDlg.cpp
上传用户:onsales
上传日期:2010-01-31
资源大小:224k
文件大小:11k
源码类别:

网络编程

开发平台:

Visual C++

  1. // SpeakDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Speak.h"
  5. #include "SpeakDlg.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CAboutDlg dialog used for App About
  13. class CAboutDlg : public CDialog
  14. {
  15. public:
  16. CAboutDlg();
  17. // Dialog Data
  18. //{{AFX_DATA(CAboutDlg)
  19. enum { IDD = IDD_ABOUTBOX };
  20. //}}AFX_DATA
  21. // ClassWizard generated virtual function overrides
  22. //{{AFX_VIRTUAL(CAboutDlg)
  23. protected:
  24. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  25. //}}AFX_VIRTUAL
  26. // Implementation
  27. protected:
  28. //{{AFX_MSG(CAboutDlg)
  29. //}}AFX_MSG
  30. DECLARE_MESSAGE_MAP()
  31. };
  32. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  33. {
  34. //{{AFX_DATA_INIT(CAboutDlg)
  35. //}}AFX_DATA_INIT
  36. }
  37. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  38. {
  39. CDialog::DoDataExchange(pDX);
  40. //{{AFX_DATA_MAP(CAboutDlg)
  41. //}}AFX_DATA_MAP
  42. }
  43. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  44. //{{AFX_MSG_MAP(CAboutDlg)
  45. // No message handlers
  46. //}}AFX_MSG_MAP
  47. END_MESSAGE_MAP()
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CSpeakDlg dialog
  50. CSpeakDlg::CSpeakDlg(CWnd* pParent /*=NULL*/)
  51. : CDialog(CSpeakDlg::IDD, pParent)
  52. {
  53. //{{AFX_DATA_INIT(CSpeakDlg)
  54. m_Name = _T("");
  55. //}}AFX_DATA_INIT
  56. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  57. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  58. }
  59. void CSpeakDlg::DoDataExchange(CDataExchange* pDX)
  60. {
  61. CDialog::DoDataExchange(pDX);
  62. //{{AFX_DATA_MAP(CSpeakDlg)
  63. DDX_Control(pDX, IDC_IPADDRESS, m_IPADDRESS);
  64. DDX_Text(pDX, IDC_Name, m_Name);
  65. //}}AFX_DATA_MAP
  66. }
  67. BEGIN_MESSAGE_MAP(CSpeakDlg, CDialog)
  68. //{{AFX_MSG_MAP(CSpeakDlg)
  69. ON_WM_SYSCOMMAND()
  70. ON_WM_PAINT()
  71. ON_WM_QUERYDRAGICON()
  72. ON_BN_CLICKED(IDC_ConnectBTN, OnConnectBTN)
  73. ON_BN_CLICKED(IDC_CUTUPBTN, OnCutupbtn)
  74. ON_WM_TIMER()
  75. ON_BN_CLICKED(IDC_TestBTN, OnTestBTN)
  76. //}}AFX_MSG_MAP
  77. ON_MESSAGE(WM_READREADY,OnReadReady)
  78. END_MESSAGE_MAP()
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CSpeakDlg message handlers
  81. BOOL CSpeakDlg::OnInitDialog()
  82. {
  83. CDialog::OnInitDialog();
  84. // Add "About..." menu item to system menu.
  85. // IDM_ABOUTBOX must be in the system command range.
  86. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  87. ASSERT(IDM_ABOUTBOX < 0xF000);
  88. CMenu* pSysMenu = GetSystemMenu(FALSE);
  89. if (pSysMenu != NULL)
  90. {
  91. CString strAboutMenu;
  92. strAboutMenu.LoadString(IDS_ABOUTBOX);
  93. if (!strAboutMenu.IsEmpty())
  94. {
  95. pSysMenu->AppendMenu(MF_SEPARATOR);
  96. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  97. }
  98. }
  99. // Set the icon for this dialog.  The framework does this automatically
  100. //  when the application's main window is not a dialog
  101. SetIcon(m_hIcon, TRUE); // Set big icon
  102. SetIcon(m_hIcon, FALSE); // Set small icon
  103. CFile MyFile;
  104. MyFile.Open("voice.txt",CFile::modeRead);
  105.     int filelong=0;
  106. filelong=MyFile.GetLength();
  107. char pbuf[500];
  108. MyFile.Read( pbuf, sizeof( pbuf ) ); 
  109. pbuf[filelong]='';
  110. MyFile.Close(); 
  111. strIP="";
  112. m_Name="";
  113. int i=2;
  114. char sign=pbuf[0];
  115. while(pbuf[i]!='#')
  116. {
  117. strIP+=pbuf[i];
  118. i++;
  119. }
  120. i++;
  121. while(pbuf[i]!='#')
  122. {
  123. m_Name+=pbuf[i];
  124. i++;
  125. }
  126. // MessageBox(strIP);
  127. //else exit(0);
  128. //strIP="192.168.1.98";
  129. this->UpdateData(false);
  130. m_IPADDRESS.SetWindowText(strIP);
  131. // TODO: Add extra initialization here
  132. if (WSAStartup(WINSOCK_VERSION,&wsaData))
  133. {
  134. MessageBeep(MB_ICONSTOP);
  135. MessageBox("Winsock could not be initialized!", AfxGetAppName(), MB_OK|MB_ICONSTOP);
  136.     WSACleanup();
  137.     return(FALSE);
  138. }
  139. m_bWaiting=TRUE;
  140. m_bPassive=TRUE;
  141. m_bClose=TRUE;
  142. m_RemoteIP=0;
  143. m_nBlockSize=BLOCK;
  144. nID=0;
  145. chSndOut=(unsigned char*)malloc(BLOCK);
  146. Openserver();
  147. sndIn.SetBits(8);
  148. sndIn.SetBlockProp(m_nBlockSize,MAX);
  149. sndIn.SetSampleRate(11025);
  150. sndOut.SetBits(8);
  151. sndOut.SetBlockProp(m_nBlockSize,MAX);
  152. sndOut.SetSampleRate(11025);
  153. sndIn.SetTestProp(TRUE);
  154. sndIn.SetSoundOut(&sndOut);
  155. sndIn.SetCompressionObject(&cmpSend);
  156. cmpSend.SelectMethod(3);
  157. cmpReceive.SelectMethod(3);
  158. cmpReceive.SetWaveFormat(1,11025,8);
  159. cmpReceive.Initialize();
  160. cmpReceive.SetDstSamples(BLOCK/2,(unsigned char*)chRecv);
  161. cmpReceive.PrepareSpace(FALSE);
  162. if(sign=='3')
  163. {
  164. (CEdit *)GetDlgItem(IDC_ConnectBTN)->EnableWindow(FALSE);
  165. this->OnConnectBTN();
  166. }
  167. return TRUE;  // return TRUE  unless you set the focus to a control
  168. }
  169. void CSpeakDlg::OnSysCommand(UINT nID, LPARAM lParam)
  170. {
  171. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  172. {
  173. CAboutDlg dlgAbout;
  174. dlgAbout.DoModal();
  175. }
  176. else
  177. {
  178. CDialog::OnSysCommand(nID, lParam);
  179. }
  180. }
  181. // If you add a minimize button to your dialog, you will need the code below
  182. //  to draw the icon.  For MFC applications using the document/view model,
  183. //  this is automatically done for you by the framework.
  184. void CSpeakDlg::OnPaint() 
  185. {
  186. if (IsIconic())
  187. {
  188. CPaintDC dc(this); // device context for painting
  189. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  190. // Center icon in client rectangle
  191. int cxIcon = GetSystemMetrics(SM_CXICON);
  192. int cyIcon = GetSystemMetrics(SM_CYICON);
  193. CRect rect;
  194. GetClientRect(&rect);
  195. int x = (rect.Width() - cxIcon + 1) / 2;
  196. int y = (rect.Height() - cyIcon + 1) / 2;
  197. // Draw the icon
  198. dc.DrawIcon(x, y, m_hIcon);
  199. }
  200. else
  201. {
  202. CDialog::OnPaint();
  203. }
  204. }
  205. // The system calls this to obtain the cursor to display while the user drags
  206. //  the minimized window.
  207. HCURSOR CSpeakDlg::OnQueryDragIcon()
  208. {
  209. return (HCURSOR) m_hIcon;
  210. }
  211. void CSpeakDlg::OnConnectBTN() 
  212. {
  213. // TODO: Add your control notification handler code here
  214. m_bPassive=FALSE;
  215. Connect(TRUE);
  216. }
  217. void CSpeakDlg::OnCutupbtn() 
  218. {
  219. // TODO: Add your control notification handler code here
  220. char *chClose=(char*)malloc(12);
  221. wsprintf(chClose,"CLOSE");
  222. m_bClose=TRUE;
  223. sendto(m_sSend,chClose,sizeof(chClose),0,(LPSOCKADDR)&m_RemoteAddr,sizeof(m_RemoteAddr));
  224. sndIn.CloseMic();
  225. sndOut.CloseSpk();
  226. m_RemoteIP=0;
  227.     m_bWaiting=TRUE;
  228. m_bPassive=TRUE;
  229. free(chClose);
  230. }
  231. void CSpeakDlg::Openserver()
  232. {
  233. m_sSend=socket(AF_INET,SOCK_DGRAM,0); 
  234. m_sRecv=socket(AF_INET,SOCK_DGRAM,0); 
  235. m_sAccept=socket(AF_INET,SOCK_STREAM,0);
  236. char chName[64];
  237. gethostname(chName,sizeof(chName));
  238. addrSend.sin_family=AF_INET;
  239. addrSend.sin_addr.S_un.S_addr=INADDR_ANY;//inet_addr(m_chLocalIp);
  240. addrSend.sin_port=htons(SENDPORT);
  241. if (bind(m_sSend,(LPSOCKADDR)&addrSend,sizeof(addrSend))== SOCKET_ERROR)
  242. {
  243. ReportWinsockErr("Could not bind server socket.");
  244. }
  245. addrRecv.sin_family=AF_INET;
  246. addrRecv.sin_addr.S_un.S_addr=INADDR_ANY;//inet_addr(m_chLocalIp);
  247. addrRecv.sin_port=htons(RECEIVEPORT);
  248. if (bind(m_sRecv,(LPSOCKADDR)&addrRecv,sizeof(addrRecv))==SOCKET_ERROR)
  249. {
  250. ReportWinsockErr("Could not bind server socket.");
  251. }
  252. int iError=WSAAsyncSelect(m_sRecv,m_hWnd,WM_READREADY,FD_READ|FD_CLOSE);
  253. if(iError==SOCKET_ERROR)
  254. {
  255. ReportWinsockErr("Could not Select server socket.");
  256. }
  257. }
  258. BOOL CSpeakDlg::Connect(BOOL b)
  259. {
  260. unsigned long ip;
  261. char* str=new char[64];
  262. char chQuery[64];
  263. SOCKADDR_IN to;
  264. m_bClose=FALSE;
  265. if(b){
  266. //CIPAddress dlg;
  267. //if(dlg.DoModal()==IDCANCEL)
  268. // return FALSE;
  269. //else{
  270. m_RemoteIP=inet_addr(strIP);
  271. nID=SetTimer(1,10000,NULL);
  272. //}
  273. }
  274. int i=GetLocalIP(&ip,1);
  275. in_addr t;
  276. t.S_un.S_addr=ip;
  277. if(i!=0)
  278. str=inet_ntoa(t);
  279. wsprintf(chQuery,"PHONE %s",str);
  280. to.sin_family=AF_INET;
  281. to.sin_port=htons(RECEIVEPORT);
  282. to.sin_addr.S_un.S_addr=m_RemoteIP;//inet_addr("210.32.151.247"); 
  283. int iError=sendto(m_sSend,chQuery,sizeof(chQuery),0,(LPSOCKADDR)&to,sizeof(to));
  284. if(iError==SOCKET_ERROR)
  285. {
  286. ReportWinsockErr("无法建立连接.");
  287. return FALSE;
  288. }
  289. return TRUE;
  290. }
  291. int CSpeakDlg::GetLocalIP(unsigned long *ip, int len)
  292. {
  293. char chName[128];
  294. gethostname(chName,sizeof(chName));
  295. struct hostent* pHost;
  296. pHost = gethostbyname(chName); 
  297. CString str;
  298. int i=0;
  299. for(i=0; pHost!=NULL && pHost->h_addr_list[i]!=NULL; i++ ){
  300.  int j;  
  301.  for(j = 0;j<pHost->h_length;j++ ){
  302.  CString addr;
  303.  if( j > 0 )
  304.  str += "."; 
  305.   addr.Format("%u", (unsigned int)((unsigned char*)pHost->h_addr_list[i])[j]);
  306. str += addr;
  307.  }
  308.  if(i>len)
  309.  return 0;
  310. ip[i]=inet_addr(str);
  311. str.Empty();
  312.   }
  313. return i;
  314. }
  315. void CSpeakDlg::ReportWinsockErr(LPSTR lpszErrorMsg)
  316. {
  317. char chMsgBuffer[100];
  318. wsprintf(chMsgBuffer, "nWinsock error %d: %snn", WSAGetLastError(), lpszErrorMsg);
  319. MessageBox(chMsgBuffer,  AfxGetAppName(), MB_OK|MB_ICONSTOP);
  320. return;   
  321. }
  322. void CSpeakDlg::OnTimer(UINT nIDEvent) 
  323. {
  324. // TODO: Add your message handler code here and/or call default
  325. switch(nIDEvent){
  326. case 1:
  327. if(m_bPassive==FALSE){
  328. AfxMessageBox("对方不同意或者不在同一个协议下!");
  329. m_bPassive=TRUE;
  330. }
  331. case 2:{
  332.    }
  333. }
  334. CDialog::OnTimer(nIDEvent);
  335. }
  336. void CSpeakDlg::OnTestBTN() 
  337. {
  338. // TODO: Add your control notification handler code here
  339. m_nBlockSize=BLOCK;
  340. sndIn.SetBits(8);
  341. sndIn.SetBlockProp(m_nBlockSize,MAX);
  342. sndIn.SetSampleRate(11025);
  343. sndOut.SetBits(8);
  344. sndOut.SetBlockProp(m_nBlockSize,MAX);
  345. sndOut.SetSampleRate(11025);
  346. sndIn.SetTestProp(TRUE);
  347. sndIn.SetSoundOut(&sndOut);
  348. sndIn.OpenMic();
  349. sndOut.OpenSpk();
  350. }
  351. LRESULT CSpeakDlg::OnReadReady(WPARAM wParam, LPARAM lParam)
  352. {
  353. int iRecievedNum;
  354. char* ip=(char*)malloc(64);
  355. if(m_bWaiting){
  356. iRecievedNum=recv(m_sRecv,chRecv,sizeof(chRecv),0);
  357. if(iRecievedNum==SOCKET_ERROR)
  358. {
  359. ReportWinsockErr("Could not Receive the Data.");
  360. return 0L;
  361. }
  362. if(chRecv[0]=='P' && chRecv[1]=='H' ){
  363. m_bWaiting=FALSE;
  364. sscanf(chRecv,"PHONE %s",ip);
  365. m_RemoteIP=inet_addr(ip);
  366. m_RemoteAddr.sin_addr.S_un.S_addr=m_RemoteIP;
  367. m_RemoteAddr.sin_family=AF_INET; 
  368. m_RemoteAddr.sin_port=htons(RECEIVEPORT);
  369. if(m_bPassive){
  370. char *call=(char*)malloc(128);
  371. wsprintf(call,"请求语音聊天%sn, 接受么?",ip); 
  372. if(1==AfxMessageBox(call,MB_OKCANCEL))
  373. Connect(FALSE);
  374. else
  375. return 0L;
  376. free(call);
  377. }
  378. m_bPassive=TRUE;
  379. sndIn.SetTestProp(FALSE);
  380. sndIn.SetSocketParam(m_sSend,m_RemoteAddr);
  381. sndIn.OpenMic();
  382. sndOut.OpenSpk();
  383. }
  384. else{
  385. // MessageBox("Error On the Buffer");
  386. return 0L;
  387. }
  388. }
  389. else{
  390. int tmp=sizeof(m_RemoteAddr);
  391. iRecievedNum=recvfrom(m_sRecv,chRecv,BLOCK,0,(LPSOCKADDR)&m_RemoteAddr,&tmp);
  392. if((chRecv[0]=='P' && chRecv[1]=='H'))
  393. return 0L;
  394. if(chRecv[0]=='C' && chRecv[1]=='O'){
  395. if(!m_bClose)
  396. OnCutupbtn();
  397. return 0L;
  398. }
  399. if(iRecievedNum==SOCKET_ERROR)
  400. {
  401. ReportWinsockErr("无法接收数据");
  402. return 0L;
  403. }
  404. cmpReceive.SetDstSamples(iRecievedNum,(unsigned char*)chRecv);
  405. long temp=cmpReceive.UnConvert(TRUE,NULL,0);
  406. if(temp<BLOCK){
  407. cmpReceive.UnConvert(FALSE,chSndOut,temp);
  408. sndOut.WriteData((char *)chSndOut,temp);
  409. }
  410. else{
  411. cmpReceive.UnConvert(FALSE,chSndOut,BLOCK);
  412. sndOut.WriteData((char *)chSndOut,BLOCK);
  413. }
  414. }
  415. free(ip);
  416. return 0L;
  417. }