{{notification.text}}

MirGames

Студент
11.01.06 18:24
0
Короче, я решил попробовать написание сетей, и столкнулся с проблемой:
У меня, если сервер, дал команду принять лиента, а клиента в данный омент нету, то сервер, всё равно его ждёт, блокируя программу, пробовал использовать Select, но всё равно ничего не помогает использую WinSock 1.1.
Вот код:
Код
unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, WinSock, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Label1: TLabel;
   procedure FormCreate(Sender: TObject);
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 WSAData:TWSAData;
 Sockets: array of TSocket;
 Addr:TSockAddr;
 FDSet:TFDSet;
 Len, I, J: Integer;
 Buf:Pointer;
 Arg:integer=1;


implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 WSAStartup($202,WSAData);
 SetLength(Sockets,1);
 Sockets[0]:=socket(PF_INET,SOCK_STREAM,0);
 Addr.sin_family:=AF_INET;
 Addr.sin_port:=HToNs(3030);
 Addr.sin_addr.S_addr:=inet_addr('127.0.0.1');
 ZeroMemory(@Addr.sin_zero,SizeOf(Addr.sin_zero));
 bind(Sockets[0],Addr,SizeOf(TSockAddr));
 listen(Sockets[0],SOMAXCONN);
 ioctlsocket(Sockets[0],FIONBIO,Arg);


end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 FD_ZERO(FDSet);
 i:=0;
 while I<=High(Sockets) do
 Begin
   FD_SET(Sockets[i],FDSet);
   Inc(i);
 end;//While
 select(0,@FDSet,nil,nil,nil);
 I:=1;
 While I<=High(Sockets) do
 Begin
   If FD_ISSET(Sockets[i],FDSet) then
     If recv(Sockets[i],buf,0,0)<=0 then
     Begin
       closesocket(Sockets[i]);
       J:=I;
       While J<=High(Sockets) do begin Sockets[J]:=Sockets[J+1]; inc(j) end;
       Dec(i);
       SetLength(Sockets,Length(Sockets)-1);
     end//If Recv
     else
     Begin
       //Îòâå÷àåì
     end;//If Recv
     Inc(I);
 end;//While
   select(0,@FDSet,nil,nil,nil);
   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;//If FD_ISSET
 Label1.Caption:=IntToStr(Length(Sockets));
end;

end.

Это был сервер.
Вот клиент:
Код

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, WinSock,scktcomp, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Edit1: TEdit;
   Edit2: TEdit;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 Sock:TSocket;
 Data:WSAData;
 Addr:TSockAddr;
 Arg:integer=1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 WSAStartup($101,Data);
 Sock:=Socket(AF_INET,SOCK_STREAM,0);
 Addr.sin_family:=PF_Inet;
 Addr.sin_port:=HtoNS(3030);
 Addr.sin_addr.S_addr:=inet_addr('127.0.0.1');  //inet_addr('81.195.5.161');
 ZeroMemory(@Addr.sin_zero,SizeOf(Addr.sin_zero));
 ioctlsocket(Sock,FIONBIO,Arg);
 if Connect(Sock,Addr,SizeOf(TSockAddr))=SOCKET_ERROR then ShowMessage('');

end;

end.

Если запустить, сервер и нажать на кнопку, то он блокирнётся до тех пор, пока не запустить клиент, и н нажать у него кнопку.
Пожалёйста, помогите!!! :unsure:
#1
аксакал
11.01.06 18:39
0
Сделал бы ты ioctlsocket на строку выше - всё бы заработало ;)
#2
Студент
11.01.06 18:44
0
Цитата
Сделал бы ты ioctlsocket на строку выше - всё бы заработало ;)

Странно, все равно не пашет, я поменял
listen(Sockets[0],SOMAXCONN);
ioctlsocket(Sockets[0],FIONBIO,Arg);

На
ioctlsocket(Sockets[0],FIONBIO,Arg);
listen(Sockets[0],SOMAXCONN);
Но ничего не получается, прочитал в документации, что ioctlsocket не действует на accept, но млин Select - то должен работать!!! :( :blink:
Прога виснет, усе время...
#3
Студент
11.01.06 22:20
0
Неужели никто не знает???
#4
аксакал
12.01.06 00:33
0
petyakurochkin
Почему сеть в отдельный поток не выносишь?
Или асинхронные используй.
Отредактировано: 12.01.06 00:37
#5
Студент
12.01.06 00:51
0
Если честно, то я с потоками никогд не сталкивался.. :unsure:
Цитата
Или асинхронные используй.

А как их использовать подскажи или линк дай, просто блин дали задание, а я с сетями в первый раз...
#7
Студент
14.01.06 02:23
0
Слышь, XProger, а у меня прога на линуксе/юниксе пойдёт, если я с помощью WinSock 2.2 её сделаю?
#8
аксакал
14.01.06 02:33
0
petyakurochkin
Асинхронные сокеты не пойдут.
#9
Студент
14.01.06 21:50
0
Цитата
Асинхронные сокеты не пойдут.

Можно, как нибудь через Select, а то фигово, если на линуксе не пойдёт...
В поток выносить не хочу, я не понимаю, получается что ошибка в самом WinSock???
#10
ПсихЪ
21.01.06 03:54
0
petyakurochkin
Почему не хочешь в поток вынести? Потоки рулят! (:

Цитата
получается что ошибка в самом WinSock???

Ыыы!!! Ржал, как лошадь! (:
#11
Студент
21.01.06 20:39
0
ПсихЪ
Мля, понял в чём ошибка, типа там что то связано с проверкой условия для окончания цикла у while, поэтому он обращался всегда на 1 елемент больше чем существует в массиве.
#{{post.Index}}
{{post.Author.Login}}
{{post.CreatedDate | date:'dd.MM.yy HH:mm'}}
{{post.VotesRating}}
Отредактировано: {{post.UpdatedDate | date:'dd.MM.yy HH:mm'}}