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

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

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 11.06.2010, 17:12   #1
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию Асинхронный режим работы в WinSock

я писал сервер на винсок, столкнулся с проблемой, при вызове:
Код:
ClientSocket:=Accept(ListenSocket,@SockAddr,@Len);
Управление не передается дальше по коду до тех пор пока не присоединится клиент... Как мне решить эту проблему? Пробывал загнать это в поток - тот же результат... С асинхронным режимом управление передается дальше, но не принимаются сообщения от клиента. Можете чем помочь?
"Тебе то может на меня и насрать, но твои глаза меня обожают!"
ImmortalAlexSan вне форума Ответить с цитированием
Старый 28.04.2011, 22:16   #2
dance0ff
Пользователь
 
Аватар для dance0ff
 
Регистрация: 04.09.2008
Сообщений: 12
По умолчанию

Я так понимаю, это у тебя блокирующий сокет.
Функция ACCEPT будет блокировать приложение до тех пор, пока не соединится клиент.

Если же ты сделаешь всё это в потоке, то всё будет работать на УРА.
То есть делаешь инициализацию сокета и слушаешь, всё это в одном потоке.
Как только происходит подключение, создаешь новый поток, только уже для ПОДКЛЮЧИВШЕГОСЯ клиента, соотвественно работать проще с клиентом.
Заметь потока уже 2.
Если необходимо закрыть слушающий сокет, можешь смело это делать, то есть
Код:
CloseSocket(ListenSocket);
Это никак не повлияет на работу уже подключившихся клиентов.
В подаорк тебе пример блокирующего сервера:
Код:
program winsock_server; 
//Простейшее приложение-сервер.
//Сокеты работают в блокирующем режиме.
//На каждое соединение создается отдельный поток.
{$apptype console}
uses
sysutils,
winsock,
windows;
var
vwsadata : twsadata;
vlistensocket,vsocket : tsocket;
vsockaddr : tsockaddr;
trid : thandle;
const
cport = word(33);
csigexit = 'q';
//Процедура отдельного потока для каждого клиента.
procedure socketthread;
var sockname : tsockaddr;
abuf : array of char;
vbuf : string;
vsize : integer;
s :tsocket;
bufsize : integer;
ab:string;
begin
s := vsocket;
if s = invalid_socket then exit;
vsize := sizeof(tsockaddr);
getpeername(s, sockname, vsize);
writeln(format('client accepted, remote address [%s].',[inet_ntoa (sockname.sin_addr)]));
//Определяем размер буфера чтения для сокета
vsize := sizeof(bufsize);
getsockopt(s,sol_socket,so_rcvbuf,pchar(@
bufsize),vsize);
writeln(format('receive buffer size [%d]',[bufsize]));
setlength(abuf,bufsize);
repeat
//Получаем данные. Процедура работает в блокирующем режиме,
//таким образом следующая строка кода не получит управление,
//пока не поступят данные от клиента.
vsize := recv(s,abuf[0],bufsize,0);
if vsize<=0 then break;
setlength(vbuf,vsize);
lstrcpyn(@vbuf[1],@abuf[0],vsize+1);
writeln(format('received from cleint: %s',[vbuf]));
ab:=vbuf;
if send(s,ab[1],length(ab),0)<>0 then
writeln('responsed!') else writeln('Cannot be response!');
until vbuf = 'q';
writeln(format('client disconnected, remote address [%s].',[inet_ntoa(sockname.sin_addr)]));
setlength(abuf,0);
closesocket(s);
end;
 
begin
writeln('starting application...');
//Объявляем, что программа будет использовать windows sockets.
if wsastartup($101,vwsadata)<>0 then halt(1);
writeln('using windows sockets.');
//Создаем прослушивающий сокет.
vlistensocket := socket(af_inet,sock_stream,ipproto_ip);
writeln(format('creating socket on port [%d].',[cport]));
if vlistensocket = invalid_socket then halt(1);
fillchar(vsockaddr,sizeof(tsockaddr),0);
vsockaddr.sin_family := af_inet;
vsockaddr.sin_port := htons(cport);
vsockaddr.sin_addr.s_addr := inaddr_any;
writeln('binding socket...');
//Привязываем адрес и порт к сокету.
if bind(vlistensocket,vsockaddr,sizeof(tsockaddr)) <> 0
then halt(1);
//Начинаем прослушивать.
if listen(vlistensocket,somaxconn) <> 0
then halt(1);
writeln('socket status: listening.');
repeat
//Ожидаем подключения.
vsocket := accept(vlistensocket,nil,nil);
//Клиент подключился, запускаем новый процесс на соединение.
createthread(nil,0,@socketthread,0,0,trid);
until false;
closesocket(vlistensocket);
wsacleanup;
end.
dance0ff вне форума Ответить с цитированием
Старый 28.04.2011, 22:19   #3
dance0ff
Пользователь
 
Аватар для dance0ff
 
Регистрация: 04.09.2008
Сообщений: 12
По умолчанию

Ах да, забыл добавить про потоки.
Больше 255 потоков винда не осилит, так что если пишешь сервак для большого кол-ва клиентов - Забудь про такой метод. Кури асинхронный режим.
dance0ff вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
mode режим работы открываемого файла DarkDante Общие вопросы C/C++ 3 13.03.2010 11:31
Многозадачный режим работы приложения? S_Yevgeniy Общие вопросы Delphi 16 04.09.2009 05:06
Помогите выбрать режим работы клиент сервер tarakan1983 Помощь студентам 4 24.10.2008 12:31
двухканальный режим работы photozaz Компьютерное железо 2 13.10.2008 00:05