-
Пишу я значит чат, взял пример серва из статьи королевства, там где неблокирующий режим с сообщениями, серв норм пашет, а клиент при конекте (на клик кнопки) выдает еррорину 10035, но все же конектиться (серв говорит) и с клиента текст шлеться а с серва на клиент не идет, или идет но не отображаеться (сообщения глючат по ходу). Клиент у меня тож неблокающие сокеты юзает (мож и зря ну не знаю). Если это реально, хотелось бы клиент сделать в блокирующем режиме с сообщениями...
Текст выше написал чтоб код ниже не читать (многа букаф), проблема вроде расспастраненная, сори за слэнг, настроение такое. А вот код (КЛИЕНТ): ... const WM_SocketEvent=WM_User+1; ... WSAStartup($101,Data); SK:=Socket(AF_Inet,Sock_Stream,0); Addr.sin_family:=AF_Inet; addr.sin_port:=HtoNS(7790); Addr.sin_addr.S_addr:=Inet_Addr('127.0.0.1'); FillChar(Addr.sin_zero,SizeOf(Addr.sin_zero),0); //Bind(SK,@Addr,SizeOf(Addr)); - хз надо это или не WSAAsyncSelect(SK,Handle, WM_SocketEvent,FD_Read or FD_Close or FD_CONNECT or FD_Accept); ... procedure TForm1.WMSocketEvent(var Msg:TMessage); var Sock:TSocket; SockError:Integer; begin Sock:=TSocket(Msg.WParam); SockError:=WSAGetSelectError(Msg.lParam); if SockError<>0 then begin memo1.lines.add('['+inttostr(SockError)+']Ошибка! Закрываем сокет...'); CloseSocket(Sock); Exit end; case WSAGetSelectEvent(Msg.lParam) of FD_Read: begin RECV(msg.WParam,buf,sizeof(buf),0); memo1.Lines.Add('Сообщение от сервера: '+buf); end; FD_Accept: begin memo1.lines.add('Подключен!'); end; FD_Close: begin memo1.Lines.Add('Отключение от сервера'); Shutdown(Sock,SD_Send); CloseSocket(Sock) end; FD_Connect: begin Connect(SK,@Addr,SizeOf(Addr)); memo1.lines.add('Подключен!'); end end end;
Сервер: procedure TForm1.FormCreate(Sender: TObject); var Data:TWSAData; Addr:TSockAddr; begin WSAStartup($101,Data); ServSock:=Socket(AF_Inet,Sock_Stream,0); Addr.sin_family:=AF_Inet; addr.sin_port:=HtoNS(7790); Addr.sin_addr.S_addr:=Inet_Addr('127.0.0.1'); FillChar(Addr.sin_zero,SizeOf(Addr.sin_zero),0); Bind(ServSock,@Addr,SizeOf(Addr)); Listen(ServSock,SOMaxConn); WSAAsyncSelect(ServSock,Handle, WM_SocketEvent,FD_Read or FD_Accept or FD_Close); end;
procedure TForm1.WMSocketEvent(var Msg:TMessage); var Sock:TSocket; SockError:Integer; begin Sock:=TSocket(Msg.WParam); SockError:=WSAGetSelectError(Msg.lParam); if SockError<>0 then begin CloseSocket(Sock); memo1.lines.add('['+inttostr(SockError)+']Ошибка! Закрываем сокет...'); Exit end; case WSAGetSelectEvent(Msg.lParam) of FD_Read: begin RECV(msg.WParam,buf,sizeof(buf),0); memo1.Lines.Add('Сообщение от клиента: '+buf); buf:='Сообщение получено! ('+buf+')'; Send(msg.WParam,buf,sizeof(buf),0); end; FD_Accept: begin Accept(Sock,nil,nil); memo1.lines.add('['+inttostr(WSAGetLastError)+']Клиент подключен'); end; FD_Close: begin Shutdown(Sock,SD_Send); CloseSocket(Sock); memo1.lines.add('['+inttostr(SockError)+']Клиент отключился...'); end end end;
Так вот проблема: ответ от серва в клиенте не выдает. Заранее спасибо.
-
WSAEWOULDBLOCK
(10035)
Resource temporarily unavailable.
This error is returned from operations on non-blocking sockets that cannot be completed immediately, for example recv when no data is queued to be read from the socket. It is a non-fatal error, and the operation should be retried later. It is normal for WSAEWOULDBLOCK to be reported as the result from calling connect on a non-blocking SOCK_STREAM socket, since some time must elapse for the connection to be established.
-
Пасиба, я знаю что оно означает, хотел бы узнать где ошибка в клиенте, почему он не отображает текст присылаемый с сервака
-
> а клиент при конекте (на клик кнопки)
Ну и где этот код при нажатии кноки? Код подключения?
-
procedure TForm1.Button1Click(Sender: TObject); begin Connect(SK,@Addr,SizeOf(Addr)); end;
-
а почему тогда у тебя в FD_CONNECT ещё раз вызывается connect? м?
-
а это уже эксперименты, прежде чем сюда лезть пробовал по всякому, изначально конект был на кнопке а в FD_CONNECT его небыло, и выдавал ошибку.
-
> а это уже эксперименты
А какие могут быть "экспереименты", если событие говорит о факте коннекта ?
> КЛИЕНТ
> FD_Accept:
А это что за "эксперименты" ?
FD_ACCEPT - это событие исключительно серверной стороны ! На стороне клиента оно никогда не возникнет. Зато и на серверной и на клиентской сторонах крайне выжным является событие FD_WRITE, реакция на которое у тебя отсутствует вообще.
-
Сергей умный чувак
-
> ass (13.09.08 23:51) [8]
"Чуваки" - они в подворотне, за клинским бегают)
-
Проще всего делать соединение в блокирующем режиме, а WSAAsyncSelect вызывать после Connect.
|