Пытаюсь передавать звук поток через сеть своим "протоколом".В начале несколько секунд все работает но потом виснет.Походу коллизия между send и recv(хотя я и могу ошибатся насчет причины).Пытался сделать на мутексах но ничего невышло Вот клиент Код (Text): HINSTANCE hInst; // текущий экземпляр TCHAR szTitle[MAX_LOADSTRING]; // Текст строки заголовка TCHAR szWindowClass[MAX_LOADSTRING]; // имя класса главного окна ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); MSG msg; HACCEL hAccelTable; LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_AUDIOCLIENT, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_AUDIOCLIENT)); while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_AUDIOCLIENT)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_AUDIOCLIENT); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); SetWindowPos(hWnd,HWND_TOP,100,100,300,150,SWP_SHOWWINDOW); return TRUE; } WAVEFORMATEX wf; struct protostruct { unsigned long comma; unsigned long datasz; }; SOCKET s; HWAVEIN in; char *sendbuf; char *recvbuf; int sbSZ=0,rbSZ=0; WAVEHDR whS; HWAVEOUT play; CRITICAL_SECTION cs; WAVEHDR wd; HANDLE thr; DWORD WINAPI StartDataExchange(LPVOID lParam) { HWND hWnd=(HWND)lParam; wf.cbSize=0; wf.wFormatTag=WAVE_FORMAT_PCM; wf.wBitsPerSample=16; wf.nSamplesPerSec=16000L; wf.nChannels=1; wf.nBlockAlign=2; wf.nAvgBytesPerSec=wf.nSamplesPerSec*wf.nBlockAlign; protostruct pt; ZeroMemory(&pt,sizeof(protostruct)); pt.comma=0; pt.datasz=0; send(s,(char*)&pt,sizeof(protostruct),0); send(s,(char*)&wf,sizeof(WAVEFORMATEX),0); sbSZ=(wf.nBlockAlign*wf.nSamplesPerSec)/8; rbSZ=sbSZ; recvbuf=new char[rbSZ]; sendbuf=new char[sbSZ]; waveInOpen(&in,WAVE_MAPPER,&wf,(DWORD)hWnd,0L, CALLBACK_WINDOW); whS.lpData=sendbuf; whS.dwBufferLength=sbSZ; waveInPrepareHeader(in,&whS,sizeof(WAVEHDR)); waveInAddBuffer(in,&whS,sizeof(WAVEHDR)); ZeroMemory(&pt,sizeof(protostruct)); HANDLE mut=CreateMutex(NULL,FALSE,"synhro"); WaitForSingleObject(mut,INFINITE); waveInStart(in); recv(s,(char*)&pt,sizeof(protostruct),0); //MessageBox(0,"c","",MB_OK); if(pt.comma=1) { int recvsz=0, acum=0; for(;;) { recvsz=recv(s,recvbuf,pt.datasz,0); recvbuf+=recvsz; acum=acum+recvsz; if(acum==pt.datasz) { recvbuf-=pt.datasz; break; } } ReleaseMutex(mut); waveOutOpen(&play,WAVE_MAPPER,&wf,(DWORD)hWnd, 0L, CALLBACK_WINDOW); wd.dwBufferLength=rbSZ; wd.lpData=recvbuf; waveOutPrepareHeader(play, &wd, sizeof(WAVEHDR)); waveOutWrite(play, &wd, sizeof(WAVEHDR)); } return(0); } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_CREATE: { CreateWindow("button",TEXT("Start"),WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON ,20,50,70,30,hWnd,(HMENU)200,hInst,NULL); }break; case WM_NCCREATE: { LPCREATESTRUCT lpcp=(LPCREATESTRUCT)lParam; lpcp->style &= (~WS_MAXIMIZEBOX ); lpcp->style &= (~WS_SIZEBOX ); SetWindowLong(hWnd, GWL_STYLE, lpcp->style); return true; } break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); if(LOWORD(wParam)==200) { SOCKADDR_IN adr; WSADATA wsd; WSAStartup(MAKEWORD(2,0),&wsd); adr.sin_family=AF_INET; adr.sin_addr.s_addr=inet_addr("127.0.0.1"); adr.sin_port=htons(2020); s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); connect(s,(sockaddr*)&adr,sizeof(SOCKADDR_IN)); thr=CreateThread(0,0,&StartDataExchange,(void*)hWnd,0,0); } case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: добавьте любой код отрисовки... EndPaint(hWnd, &ps); break; case MM_WIM_DATA: { //WaitForSingleObject(thr,INFINITE); waveInUnprepareHeader(in, &whS, sizeof(WAVEHDR)); protostruct pt; ZeroMemory(&pt,sizeof(protostruct)); pt.comma=1; pt.datasz=sbSZ; HANDLE mut=CreateMutex(NULL,FALSE,"synhro"); WaitForSingleObject(mut,INFINITE); send(s,(char*)&pt,sizeof(protostruct),0); send(s,sendbuf,sbSZ,0); ReleaseMutex(mut); memset(sendbuf,NULL,sbSZ); whS.lpData=sendbuf; waveInPrepareHeader(in,&whS,sizeof(WAVEHDR)); waveInAddBuffer(in,&whS,sizeof(WAVEHDR)); waveInStart(in); }break; case MM_WOM_DONE: { WaitForSingleObject(thr,INFINITE); waveOutUnprepareHeader(play,&wd,sizeof(WAVEHDR)); protostruct pt; ZeroMemory(&pt,sizeof(protostruct)); HANDLE mut=CreateMutex(NULL,FALSE,"synhro"); WaitForSingleObject(mut,INFINITE); recv(s,(char*)&pt,sizeof(protostruct),0); if(pt.comma=1) { int recvsz=0, acum=0; for(;;) { recvsz=recv(s,recvbuf,pt.datasz,0); recvbuf+=recvsz; acum=acum+recvsz; if(acum==pt.datasz) { recvbuf-=pt.datasz; break; } } } ReleaseMutex(mut); waveOutOpen(&play,WAVE_MAPPER,&wf,(DWORD)hWnd, 0L, CALLBACK_WINDOW); wd.dwBufferLength=rbSZ; wd.lpData=recvbuf; waveOutPrepareHeader(play, &wd, sizeof(WAVEHDR)); waveOutWrite(play, &wd, sizeof(WAVEHDR)); }break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } Вот эхо сервер: Код (Text): HINSTANCE hInst; // текущий экземпляр TCHAR szTitle[MAX_LOADSTRING]; // Текст строки заголовка TCHAR szWindowClass[MAX_LOADSTRING]; // имя класса главного окна // Отправить объявления функций, включенных в этот модуль кода: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); MSG msg; HACCEL hAccelTable; LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_AUDIOSERVER, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_AUDIOSERVER)); while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_AUDIOSERVER)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_AUDIOSERVER); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } SOCKET s,client; struct protostruct { unsigned long comma; unsigned long datasz; }; WAVEFORMATEX wf; DWORD WINAPI listT(LPVOID lParam) { HWND hWnd=(HWND)lParam; SOCKADDR_IN cadr; listen(s,1); int szcadr=sizeof(SOCKADDR_IN); client=accept(s,(sockaddr*)&cadr,&szcadr); protostruct pt; ZeroMemory(&pt,sizeof(protostruct)); char *buf=new char[1024*512]; memset(buf,NULL,1024*512); for(;;) { recv(client,(char*)&pt,sizeof(protostruct),0); switch(pt.comma) { case 0: { recv(client,(char*)&wf,sizeof(WAVEFORMATEX),0); wsprintf(buf,"%d",wf.nChannels,MB_OK); //MessageBox(0,buf,"",MB_OK); }break; case 1: { //MessageBox(0,"s","",MB_OK); int recsz=0,acum=0; for(;;) { recsz=recv(client,buf,pt.datasz,0); acum=acum+recsz; buf+=recsz; if(acum==pt.datasz){buf-=pt.datasz;break;} } ZeroMemory(&pt,sizeof(protostruct)); pt.comma=1; pt.datasz=acum; send(client,(char*)&pt,sizeof(protostruct),0); send(client,buf,acum,0); }break; case 2: { closesocket(s); closesocket(client); WSACleanup(); PostMessage(hWnd,WM_QUIT,0,0); }break; ZeroMemory(&pt,sizeof(protostruct)); } } return(0); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Сохранить дескриптор экземпляра в глобальной переменной hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, SW_HIDE); UpdateWindow(hWnd); SOCKADDR_IN adr; WSADATA wsd; WSAStartup(MAKEWORD(2,0),&wsd); adr.sin_addr.s_addr=0; adr.sin_family=AF_INET; adr.sin_port=htons(2020); s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); bind(s,(sockaddr *)&adr,sizeof(SOCKADDR_IN)); CreateThread(0,0,&listT,(void*)hWnd,0,0); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: добавьте любой код отрисовки... EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } Я догадываюсь что привязка к оконным сообщениям нужна для синхронизации с устройством.НО вот как все это хозяйство синхронизировать с сокетом?
_nic А зачем мутексы то? Тут же все должно быть до безобразия просто со звуком-то. Есть данные для отправки - отправляем, есть данные для чтения - читаем и воспроизводим. Какая тут синхронизация? Начни с простого. И потом, у тебя ни разу не уделено внимания обработке ошибок, ф-ции рецв и сенд могут возвращать и 0 и -1, у тебя же нет ни одной проверки на это. Как виснет? Где виснет? Просто рецв ждет чего-то или где-то зацикливается?
Схема такая : пакет ушол-> пакет пришол<- пакет ушол-> пакет пришол<- Естественно что сокет(по схеме выше видно что все идет через один порт) надо синхронизовать,с микрофоном и воспроизведением,дабы небыло коллизий между recv и send.
_nic Учите мат часть. Пока RFC на TCP и UDP не перескажите дальше нет смысла общаться. А еще прочитайте про send и recv. До мьютексов вам еще рано. А еще походу и звук неправильно читаете поэтому все и виснет. Не говоря уже про процессы.
Имеешь что то против нерусских на этом форуме? Извините но я не ваш студент.Не хотите писать по существу не пишите.
> Имеешь что то против нерусских на этом форуме? Нерусский - это тот, кто смело ложит на правила языка, на котором он говорит?
когда все виснет и прога была запущена не из под отладчика можно взять process explorer посмотреть стеки потоков и приаттачить ольку обычно все становится ясно по крайней мере место где виснет найдеш а из за чего надо будет думать
да там особо и рассказывать то не о чем открываеш process explorer смотриш бэктрейс записываеш в блокнот аттачиш ольку ну и по обстановке а вообще можно и студийный отладчик приаттачить там в меню debug->attach to process выбрать свою зависшую прогу и подллючится ну а дальше так же бэктрейс посмотреть тем более если ты к разрабатываемой проге приаттачиш студия красиво бэктрэйс покажет с именами твоих функций кстати книжку bugslayer'а Роббинс Дж. - Отладка приложений для Microsoft .NET и Microsoft Windows (2004)(14 Mb).djvu найдите скачайте и пользуйтесь ей как справочником там хорошо расписан отладчик студийный и как в нем максимально эффективно отлаживать
Судя по процесс эксплореру в обоих процессах одновременно send висит.Это что ли причина?Ведь send в отличии от recv неждет он просто данные отсылает.