Форум: "Сети";
Текущий архив: 2007.08.19;
Скачать: [xml.tar.bz2];
ВнизWinsock API и accept Найти похожие ветки
← →
_darksidenv (2007-01-07 12:32) [0]У меня вопрос. Я написал серверное приложение в console application, потом тот же самый код я перенес на windows application, при нажатии на кнопку программа виснет, а в консольном не висло, виснет на операторе accept... что не так? заранее спасибо!
← →
Dmitrij_K (2007-01-07 22:28) [1]Ошибка в 17 строке.
← →
kaZaNoVa © (2007-01-08 13:11) [2]_darksidenv (07.01.07 12:32)
надо делать в потоке
← →
kaZaNoVa © (2007-01-08 13:13) [3]+ я бы еще на каждый коннект по потоку бы делал ...:
repeat
//Ожидаем подключения.
S1:=accept(vListenSocket,nil,nil);
//Клиент подключился, запускаем новый процесс на соединение.
CreateThread(nil,0,@SocketThread,nil,0,trId);
until false;
closesocket(vListenSocket);
WSACleanup;
← →
_darksidenv (2007-01-09 08:35) [4]Ну вот, что тут не правильно? Это пример с инета...читал литературу и походу делал, только пример на консольном приложении...
procedure Status(s: string);
begin
form1.Memo1.Lines.Add(s);
end;
procedure SocketThread;
var SockName : TSockAddr;
aBuf : array of char;
vBuf : string;
vSize : integer;
s :TSocket;
BufSize : integer;
begin
s := sSocket;
if s = INVALID_SOCKET then exit;
vSize := SizeOf(TSockAddr);
getpeername(s, SockName, vSize);
Status(format("Клиент подключился, удаленный адрес [%s].",[inet_ntoa (SockName.sin_addr)]));
vSize := sizeOf(BufSize);
getsockopt(s,SOL_SOCKET,SO_RCVBUF,PChar(@BufSize),vSize);
Status(format("Получен буфер размером [%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);
Status(format("Получено от клиента: %s",[vBuf]));
until vBuf = "q";
Status(format("Клиент отключился [%s].",[inet_ntoa(SockName.sin_addr)]));
SetLength(aBuf,0);
closesocket(s);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Status("Starting application...");
if WSAStartup($101,sWSAData)<>0 then application.terminate;
Status("Using Windows Sockets.");
sListenSocket := socket(AF_INET,SOCK_STREAM,0);
Status(format("Creating socket on port [%d].",[cPort]));
if sListenSocket = INVALID_SOCKET then application.terminate;
FillChar(sSockAddr,SizeOf(TSockAddr),0);
sSockAddr.sin_family := AF_INET;
sSockAddr.sin_port := htons(cPort);
sSockAddr.sin_addr.S_addr := 0;
Status("Binding socket...");
if bind(sListenSocket,sSockAddr,SizeOf(TSockAddr)) <> 0
then application.terminate;
if listen(sListenSocket,SOMAXCONN) <> 0 then application.terminate;
Status("Socket status: listening.");
repeat
sSocket := accept(sListenSocket,nil,nil);
CreateThread(nil,0,@SocketThread,0,0,trId);
until false;
closesocket(sListenSocket);
WSACleanup;
end;
При нажатии на кнопку, просто виснет программа и всё.., что не так?
← →
Сергей М. © (2007-01-09 08:46) [5]
> что не так?
Практически все. Начиная с форматирования текста программы.
← →
_darksidenv (2007-01-09 09:05) [6]Я тут полистал форум ради интереса. Тут у всех так заведено говорить кратко, не по теме и всячески ничем не помогать? Я конкретно привёл пример, который был в книге, он не работает, вы мне пишите про форматирование текста... не хотите помочь, не надо, вас никто не упрашивает...проще промолчать на мой взгляд. Или сейчас пойдут опять утверждения, что-то типа: "поставте правильно вопрос, конкретизируйте проблему, опишите поподробней...и т.д, и т.п."...
← →
Сергей М. © (2007-01-09 09:25) [7]
> вы мне пишите про форматирование текста
Приведение элементарно неотформатированного кода есть элементарное неуважение к собеседнику. Ты его продемонстрировал в полной красе, что же ты хочешь в ответ ?
> Я конкретно привёл пример, который был в книге, он не работает
Разобраться пробовал ? Брейкпойнт на вызове CreateThread() ставил ? ловил ?
Справку по CreateThread штудировал ? Про рекомендации Борланда в части BeginThread vs CreateThread слышал ? Про потоконебезопасность визуальных VCL-контролов в курсе ?
Куча вопросов к тебе .. Каждый из них требует серьезной корректировки примера, вплоть до полной его переделки от начала до конца, что равносильно ответу "Практически все" на вопрос "Что не так ?".
> виснет на операторе accept
В блокирующем режиме это абсолютно нормально.
"Вис" прекращается немедленно как только в очереди запросов на подключение слушающим гнездом обнаруживается хотя бы один запрос.
← →
_darksidenv (2007-01-09 09:37) [8]Сергей М. > Cпасибо, знаю в каком направлении идти...буду разбираться в потоках. А на вопрос "разбираться пробовал?", я разбирался в Winsock API...
← →
Сергей М. © (2007-01-09 09:47) [9]
> я разбирался в Winsock API
Тогда непонятно, что тебя удивляет в "виснет на операторе accept"
> буду разбираться в потоках
Оно, конечно, весьма полезно.
Только для начала следовало бы разобраться в работе с Winsock в однопоточном приложении, и уж затем при явной необходимости реализовать мультипоточность.
← →
_darksidenv (2007-01-09 11:29) [10]Сергей М.> Спасибо ещё раз, да, действительно, при подключении к серверу форма начинает передвигаться и "вис" проходит. А нельзя ли как-нидь избежать заступоривания формы на одном месте. Например, при использовании стандартных VCL компонентов для работы с сокетами, при выставлении параметра Active в true... форму можно двигать...наверное, ламерский вопрос :) но всё же интересно можно ли этого достигнуть? т.е. другими словами, чтобы по достижении программы оператора accept и переходя в ждущий режим можно было бы производить другие действия на форме? заранее спасибо.
← →
Сергей М. © (2007-01-09 11:59) [11]
> _darksidenv (09.01.07 11:29) [10]
Для Winsock 1.x cуществует минимум два решения твоей "проблемы оживления" GUI:
1. Перевод слушающего гнезда в неблокирующий режим (см. ioctlsocket), с возможным задействованием асинхронных нотификаций (см. WSAAsyncSelect, WSAEventSelect и событие FD_ACCEPT)
2. Перенос логики работы со слушающим гнездом в дополнительный кодовый поток.
Если необходимо, можно сочетать 1 и 2.
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2007.08.19;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.05 c