Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.11.2011, 04:48   #1
fawr
Пользователь
 
Регистрация: 19.10.2009
Сообщений: 25
По умолчанию СreateThread

сокеты пробую ковырять, вырезал из примеров откуда-то с форума...
на форме по нажатию клавиши выполняются:
Код:
numcl = 0;
				WORD wVersionRequested;
				WSADATA wsaData;
				int err;
				wVersionRequested = MAKEWORD( 2, 2 );
				err = WSAStartup( wVersionRequested, &wsaData );
				if ( err != 0 )
					return;
				SOCKET s=socket(AF_INET,SOCK_STREAM,0);
				sockaddr_in local_addr;
				local_addr.sin_family=AF_INET;
				local_addr.sin_port=htons(1280);
				local_addr.sin_addr.s_addr=0;
				bind(s,(sockaddr *) &local_addr,sizeof(local_addr));
				int c=listen(s,5);
				label2->Text = "Server receive ready";
				SOCKET client_socket;
				sockaddr_in client_addr;
				int client_addr_size=sizeof(client_addr);
				while((client_socket=accept(s,(sockaddr *)&client_addr, &client_addr_size)))
				{
					numcl++;
					print();
					DWORD thID;
					// thID идентификатор типа DWORD
				CreateThread(NULL,NULL,ThreadFunc,&client_socket,NULL,&thID);
				}
описание ThreadFunc в паблике выше:
Код:
DWORD WINAPI ThreadFunc(LPVOID client_socket)
			{
				SOCKET s2=((SOCKET *) client_socket)[0];
				char buf[100];
				char res[100], *z;
				strcpy(res, "");
				while(recv(s2,buf,sizeof(buf),0))
				{
					int n=0,k=0;
					k=strlen(buf)-1;
					if (k>=15)
					{
						z=buf;
						sscanf(z+=n," %s%n",res, &n);
//						label2->Text = (String)buf;
						send(s2,res,100,0);
					}
					else
						send(s2,"The string lenght is less than 15 symbols",100,0);
				}
				closesocket(s2);
				return 0;
			}
в консоле работает как надо, но в виде функции в коде формы не хочет - указывает на строчку ошибка С3867:
CreateThread(NULL,NULL,ThreadFunc,& client_socket,NULL,&thID);

понятно что это не консоль и в функцию надо передавать параметры раз определены:
Код:
CreateThread(NULL,NULL,ThreadFunc(&client_socket),&client_socket,NULL,&thID);
однако ошибка С2664: не преобразуются типы...

подскажите как быть?
fawr вне форума Ответить с цитированием
Старый 23.11.2011, 10:51   #2
zotox
Форумчанин
 
Регистрация: 09.09.2008
Сообщений: 395
По умолчанию

Цитата:
в функцию надо передавать параметры раз определены
В данном случае это не так!
Когда вы пишите так:
Код:
CreateThread(NULL,NULL,ThreadFunc(&client_socket),&client_socket,NULL,&thID);
То сначала вызывается функция ThreadFunc, и потом результат этой функции возвр. в третий аргумент CreateThread. И только после вызова ThreadFunc вызывается CreateThread. Третий аргумент CreateThread - это просто адрес функции. А параметры этой функции находятся в четвертом аргументе.
Т.е. в данном случае так не правильно:
Код:
CreateThread(NULL,NULL,ThreadFunc(&client_socket),&client_socket,NULL,&thID);
А правильно так:
Код:
CreateThread(NULL,NULL,ThreadFunc,& client_socket,NULL,&thID);
Цитата:
подскажите как быть?
Перед "DWORD WINAPI ThreadFunc(LPVOID client_socket)" (который в паблике)
поставьте "static".
Должно получиться так:
Код:
static DWORD WINAPI ThreadFunc(LPVOID client_socket)
zotox вне форума Ответить с цитированием
Старый 23.11.2011, 18:29   #3
fawr
Пользователь
 
Регистрация: 19.10.2009
Сообщений: 25
По умолчанию

дада, спасибо
в поиске решения этой проблемы я натыкался на предполагаемое решение: сделать все функции статическими, либо все глобальными...
static пробовал писать, однако дальше возникает ошибка С2664 касающаяся именно этого 3его параметра:

error C2664: 'CreateThread' : cannot convert parameter 3 from 'DWORD (__clrcall *)(LPVOID)' to 'LPTHREAD_START_ROUTINE'

после этого начинаешь колдовать, пробовать менять тип - не получается
fawr вне форума Ответить с цитированием
Старый 23.11.2011, 20:47   #4
fawr
Пользователь
 
Регистрация: 19.10.2009
Сообщений: 25
По умолчанию

как то решилась проблема через:
CreateThread(NULL,NULL,(LPTHREAD_ST ART_ROUTINE)ThreadFunc,&client_sock et,NULL,&thID);
и подключением библиотек

вот теперь виснет на
while((client_socket=accept(s,(sock addr *)&client_addr, &client_addr_size)))
fawr вне форума Ответить с цитированием
Старый 24.11.2011, 04:34   #5
fawr
Пользователь
 
Регистрация: 19.10.2009
Сообщений: 25
По умолчанию

стало понятно почему циклится и виснет)

дальше проблема снова проблема по сабжу:
при подключении клиента программа вылетает с неуловимым исключением на строке со злосчастным
CreateThread(NULL,NULL,(LPTHREAD_ST ART_ROUTINE)ThreadFunc,&client_sock et,NULL,&thID);

как быть? и это при том что в консоле работает без всех этих проблем.
fawr вне форума Ответить с цитированием
Старый 24.11.2011, 10:53   #6
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

fawr

CreateThread(NULL,NULL,(LPTHREAD_ST ART_ROUTINE)ThreadFunc,&client_sock et,NULL,&thID);

убери отсюда приведение типа к LPTHREAD_START_ROUTINE - это лишнее и только захламляет код и оттягивает ошибку до момента выполнения, что мы и наблюдаем.

правильный формат вызова:

CreateThread(NULL, 0, &ThreadProc, ..., 0, &threadID);

прототип функции-мембера, работающей в потоке:

static DWORD WINAPI ThreadProc(void* Param);

если при этом происходят ошибки компиляции, значит код написан криво. Возможно, это китайский компилятор. Выкинь его и возьми нормальный.
Rififi вне форума Ответить с цитированием
Старый 26.11.2011, 13:45   #7
fawr
Пользователь
 
Регистрация: 19.10.2009
Сообщений: 25
По умолчанию

думал обойтись без потоков, но если делать приложение клиент-сервер - не обойтись.
прочитал что CreateThread это не очень, а _beginthreadex лучше.
функция вот: static void WINAPI ThreadFunc(void* Param)
создание потока вот: _beginthreadex(NULL,0,ThreadFunc,&c lient_socket,0,&thID);

о5 двадцать пять - теперь не стыкуется:
error C2664: '_beginthreadex' : cannot convert parameter 3 from 'void (__clrcall *)(void *)' to 'unsigned int (__stdcall *)(void *)'

http://programmersforum.ru/showthread.php?t=118035 - тут советуют __clrcall вообще отключить...
каким образом это сделать? или можно как-то конвертировать?
fawr вне форума Ответить с цитированием
Старый 26.11.2011, 14:23   #8
haruhi
Форумчанин
 
Аватар для haruhi
 
Регистрация: 05.10.2011
Сообщений: 368
По умолчанию

Rififi же написал как надо объявлять функцию
static DWORD WINAPI ThreadProc(void* Param);
а у вас
static void WINAPI ThreadFunc(void* Param)
Не стоит будить спящего Бога! (с) Меланхолия Харухи Судзумии
haruhi вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц