program Chat_Server;
uses constants, winsock, windows, sysutils;
const
my_port = 666;
max_connect_count = 64{SoMaxConn};
var Sockets:array[0 .. max_connect_count-1] of TSocket; // Њ ббЁў б®ЄҐв®ў
connect_count : integer; // Љ®«ЁзҐбвў® ᮥ¤Ё­Ґ­Ё©
Addr : TSockAddr; // Ђ¤аЁб Є«ЁҐ­в
Data : TWSAData; // ’ ­­лҐ ® ЎЁЎ«Ё®вҐЄҐ б®ЄЄҐв®ў
Len, I, J, n : Integer; //
FDWriteSet,
FDErrorSet,
FDReadSet : TFDSet; // Њ­®¦Ґбвў® б®ЄҐв®ў Ј®в®ўле Є з⥭Ёо
FDSetCount : LongInt; // Љ®«ЁзҐбвў® Ј®в®ўле б®ЄҐв®ў
ReadTimeVal : TTimeVal; // Џа®¬Ґ¦гв®Є ®¦Ё¤ ­Ёп з⥭Ёп
msg_buffer : array[0 .. 1024] of byte; // ЎгдҐа б®®ЎйҐ­Ё©
msg_buffer_length : integer; // ¤«Ё­ бзЁв ­­ле ¤ ­­ле
error : integer; // Љ®¤ ®иЁЎЄЁ
{} Arg : u_long;
{} comand : dword;
begin
writeln('Start my chat server.');
writeln;
write('Initialisation = ');
if WSAStartup($0101, Data) <> 0 then
begin
ShowError('Error', WSAGetLastError);
exit;
end;
writeln('Failed');
// WSAStartup($101,Data);
write('Create Socket = ');
Sockets[0]:=socket(AF_INET,SOCK_STREAM,0{IPProto_TCP});
if Sockets[0]<0 then
begin
ShowError('Error', WSAGetLastError);
exit;
end;
writeln('Failed');
// Sockets[0]:=Socket(AF_Inet,Sock_Stream,0);
Addr.sin_family:=AF_Inet;
Addr.sin_port:=HToNS(my_port);
Addr.sin_addr.S_addr:=InAddr_Any;
FillChar(Addr.Sin_Zero,SizeOf(Addr.Sin_Zero),0);
write('Open Socket = ');
if bind(Sockets[0],@Addr,SizeOf(TSockAddr)) = Socket_Error then
begin
ShowError('Error', WSAGetLastError);
exit;
end;
writeln('Failed');
// Bind(Sockets[0],Addr,SizeOf(TSockAddr));
write('Listen Socket = ');
if Listen(Sockets[0],max_connect_count) = Socket_Error then
begin
ShowError('Error', WSAGetLastError);
exit;
end;
writeln('Failed');
connect_count := 1;
// Listen(Sockets[0],SoMaxConn);
ReadTimeVal.tv_sec:=5;
ReadTimeVal.tv_usec:=0000;
while True do
begin
// 1. ”®а¬Ёа®ў ­ЁҐ ¬­®¦Ґбвў б®ЄҐв®ў
writeln('1 - FD_Zero = ”®а¬Ёа®ў ­ЁҐ ¬­®¦Ґбвў б®ЄҐв®ў');
FD_Zero(FDReadSet);
FD_Zero(FDWriteSet);
FD_Zero(FDErrorSet);
for I:=low(Sockets) to High(Sockets) do
begin
FD_Set(Sockets,FDReadSet);
FD_Set(Sockets,FDWriteSet);
FD_Set(Sockets,FDErrorSet);
end;
// 2. Џа®ўҐаЄ Ј®в®ў­®бвЁ б®ЄЄҐв
writeln('2.B - Select = Џа®ўҐаЄ Ј®в®ў­®бв б®ЄЄҐв ');
FDSetCount := Select(0,@FDReadSet,{@FDWriteSet,@FDErrorSet,}nil, nil, @ReadTimeVal);
writeln('2.E');
writeln('- = ',FDSetCount);
if FDSetCount = Socket_Error then ShowError('Error', WSAGetLastError);
if FDSetCount>0 then
for I:=low(Sockets) to High(Sockets) do
begin
if FD_IsSet(Sockets,FDReadSet)
then write(i,' ');
end;
readln;
end;
end.
Не работает Select в сокетах
Есть код
Код:
Так вот на функции Select возвращается Socket_Error и ни как не меняет FDReadSet, при этом WSAGetLastError ни чего не возвращает.
В чём проблема?
Примечание : может конечно обратился не туда, пишу на FreePascal.
Зарание спасибо.
Смущает получение указателей на параметры в вызове Select. Как вообще описана функция?
Цитата: makbeth
Смущает получение указателей на параметры в вызове Select. Как вообще описана функция?
Так и должно быть...
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1021#11
Вот код примера из данной статьи
Код:
var Sockets:array of TSocket;
Addr:TSockAddr;
Data:TWSAData;
Len,I,J:Integer;
FDSet:TFDSet;
begin
WSAStartup($101,Data);
SetLength(Sockets,1);
Sockets[0]:=Socket(AF_Inet,Sock_Stream,0);
Addr.sin_family:=AF_Inet; Addr.sin_port:=HToNS(5514);
Addr.sin_addr.S_addr:=InAddr_Any; FillChar(Addr.Sin_Zero,SizeOf(Addr.Sin_Zero),0);
Bind(Sockets[0],Addr,SizeOf(TSockAddr));
Listen(Sockets[0],SoMaxConn);
while True do begin
// 1. Формирование множества сокетов
FD_Zero(FDSet);
for I:=0 to High(Sockets) do
FD_Set(Sockets,FDSet);
// 2. Проверка готовности сокетов
Select(0,@FDSet,nil,nil,nil);
// 3. Чтение запросов клиентов тех сокетов, которые готовы к этому
I:=1;
while I<=High(Sockets) do
begin
if FD_IsSet(Sockets,FDSet) then
if Recv(Sockets,…)<=0 then
begin
// Связь разорвана, надо закрыть сокет
// и удалить его из массива
CloseSocket(Sockets);
for J:=I to High(Sockets)-1 do
Sockets[J]:=Sockets[J+1];
Dec(I);
SetLength(Sockets,Length(Sockets)-1)
end
else
begin
// Поучены данные от клиента, надо ответить
Send(Sockets,…)
end;
Inc(I)
end;
// 4. Проверка подключения нового клиента
if FD_IsSet(Sockets[0],FDSet) then
begin
// Подключился новый клиент
SetLength(Sockets,Length(Sockets)+1);
Len:=SizeOf(TSockAddr);
Sockets[High(Sockets)]:=Accept(Sockets[0],@Addr,@Len)
end
end;
Addr:TSockAddr;
Data:TWSAData;
Len,I,J:Integer;
FDSet:TFDSet;
begin
WSAStartup($101,Data);
SetLength(Sockets,1);
Sockets[0]:=Socket(AF_Inet,Sock_Stream,0);
Addr.sin_family:=AF_Inet; Addr.sin_port:=HToNS(5514);
Addr.sin_addr.S_addr:=InAddr_Any; FillChar(Addr.Sin_Zero,SizeOf(Addr.Sin_Zero),0);
Bind(Sockets[0],Addr,SizeOf(TSockAddr));
Listen(Sockets[0],SoMaxConn);
while True do begin
// 1. Формирование множества сокетов
FD_Zero(FDSet);
for I:=0 to High(Sockets) do
FD_Set(Sockets,FDSet);
// 2. Проверка готовности сокетов
Select(0,@FDSet,nil,nil,nil);
// 3. Чтение запросов клиентов тех сокетов, которые готовы к этому
I:=1;
while I<=High(Sockets) do
begin
if FD_IsSet(Sockets,FDSet) then
if Recv(Sockets,…)<=0 then
begin
// Связь разорвана, надо закрыть сокет
// и удалить его из массива
CloseSocket(Sockets);
for J:=I to High(Sockets)-1 do
Sockets[J]:=Sockets[J+1];
Dec(I);
SetLength(Sockets,Length(Sockets)-1)
end
else
begin
// Поучены данные от клиента, надо ответить
Send(Sockets,…)
end;
Inc(I)
end;
// 4. Проверка подключения нового клиента
if FD_IsSet(Sockets[0],FDSet) then
begin
// Подключился новый клиент
SetLength(Sockets,Length(Sockets)+1);
Len:=SizeOf(TSockAddr);
Sockets[High(Sockets)]:=Accept(Sockets[0],@Addr,@Len)
end
end;
А WSAGetLastError что возвращает?
А где сокеты-то сами создаются?
Код:
Sockets[0]:=socket(AF_INET,SOCK_STREAM,0{IPProto_TCP});
Ну я имею ввиду остальные-то, кроме 0-го. В массиве их 64, в сэте тоже (максимум) 64, первый то он создал а остальные добавил неинициализированными.
misha_turist, ты кстати, куда пропал? Разрулил проблему?
Цитата:
Где??? Один создал (который [0]), только с ним и работает.
тут
Код:
for I:=0 to High(Sockets) do
FD_Set(Sockets,FDSet);
FD_Set(Sockets,FDSet);
[COLOR=black][FONT=Verdana]Извините что так долго..[/FONT][/COLOR]
[COLOR=black][FONT=Verdana]Отвечаю по пунктам [/FONT][/COLOR]
- [COLOR=black][FONT=Verdana][quote=nikitozz]А WSAGetLastError что возвращает? [/quote] Функция WSAGetLastError возвращает код ошибки которая произошла т.е. если вы получили результат Socket_Error (читай "-1"), то это значит что что-то не так, а что именно не так можно узнать с помощью WSAGetLastError. [/FONT][/COLOR]
- [COLOR=black][FONT=Verdana]Проблема решена! и решена очень просто.. (кривые руки программиста голове покоя не дают ) [quote=Phodopus]...первый то он создал а остальные добавил неинициализированными. [/quote]. При заполнении множества сокетов Код:for I:=0 to High(Sockets) do FD_Set(Sockets,FDSet);Код:for I:=low(Sockets) to low(Sockets)+connect_count-1 do FD_Set(Sockets,FDSet);
Блин... а в первом примере фиксированный массив я и не заметил... :( Предполагал, что там динамический...