|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
socket: возврат данных от сервера клиенту
Здравствуйте!
Пишу для себя пример работы с сокетами. Работа в асинхронном режиме, используя WinSock. Клиент успешно подключается к серверу, данные успешно передаются от клиента к серверу, принимаются. При закрытии клиента также приходит сообщение о закрытии сокета, соединение завершается. Все хорошо, но... захотелось мне вернуть данные от сервера клиенту и все... Отправка данных клиенту вроде бы проходит без ошибок, а вот recv на клиенте ничего не возвращает. В чем может быть проблема? Ниже коды сервера и клиента. Сервер: Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, WinSock, StdCtrls; const WM_SocketEvent = WM_USER + 1; type TForm1 = class(TForm) Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } ServSock: TSocket; aBuf : array of char; procedure WMSocketEvent(var msg: TMessage); message WM_SocketEvent; procedure send_to_client(p_sock: TSocket); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var Data: TWSAData; Addr: TSockAddr; begin WSAStartup($101, Data); ServSock := Socket(AF_Inet, Sock_Stream, IPPROTO_IP); if ServSock = INVALID_SOCKET then ShowMessage('Îøèáêà'); Addr.sin_family := AF_Inet; Addr.sin_addr.S_addr := inet_addr('127.0.0.1'); Addr.sin_port := HToNS(3320); FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0); Bind(ServSock, Addr, SizeOf(TSockAddr)); Listen(ServSock, SOMaxConn); WSAAsyncSelect(ServSock, Handle, WM_SocketEvent, FD_Read or FD_Accept or FD_Connect or FD_Close); end; procedure TForm1.WMSocketEvent(var msg: TMessage); var Sock: TSocket; SockError: integer; SockName : TSockAddr; vSize: integer; vBuf: string; BufSize : integer; begin Sock := TSocket(msg.WParam); SockError := WSAGetSelectError(msg.LParam); if SockError <> 0 then begin ShowMessage('Îøèáêà'); CloseSocket(Sock); Exit; end; vSize := SizeOf(TSockAddr); GetPeerName(Sock, SockName, vSize); case WSAGetSelectEvent(msg.LParam) of FD_Read: begin vSize := recv(Sock,aBuf[0],BufSize,0); if vSize <= 0 then exit; SetLength(vBuf,vSize); lstrcpyn(@vBuf[1],@aBuf[0],vSize + 1); Memo1.Lines.Add(format('Received from client: %s',[vBuf])); send_to_client(Sock); end; FD_Accept: begin Sock := Accept(ServSock, nil, nil); vSize := SizeOf(TSockAddr); GetPeerName(Sock, SockName, vSize); Memo1.Lines.Add(format('Client accepted, remote address [%s].',[inet_ntoa(SockName.sin_addr)])); //Îïðåäåëÿåì ðàçìåð áóôåðà ÷òåíèÿ äëÿ ñîêåòà vSize := sizeOf(BufSize); getsockopt(Sock,SOL_SOCKET,SO_RCVBUF,PChar(@BufSize),vSize); Memo1.Lines.Add(format('Receive buffer size [%d]',[BufSize])); SetLength(aBuf,BufSize); end; FD_Close: begin Shutdown(Sock, SD_Send); Memo1.Lines.Add(format('Client closed, remote address [%s].',[inet_ntoa(SockName.sin_addr)])); CloseSocket(Sock); end; end; end; procedure TForm1.send_to_client(p_sock: TSocket); var buf: string; begin buf := 'asdasd'; if send(p_sock,buf[1],Length(buf),0) = SOCKET_ERROR then ShowMessage('Îøèáêà'); end; procedure TForm1.FormDestroy(Sender: TObject); begin CloseSocket(ServSock); WSACleanup; end; end. Клиент: Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, WinSock; type TForm1 = class(TForm) Edit1: TEdit; Button1: TButton; Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } ServSock: TSocket; aBuf: array of char; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var Data: TWSAData; Addr: TSockAddr; vSize, BufSize : integer; begin WSAStartup($101, Data); ServSock := Socket(AF_Inet, Sock_Stream, IPPROTO_IP); if ServSock = INVALID_SOCKET then ShowMessage('Îøèáêà'); Addr.sin_family := AF_Inet; Addr.sin_addr.S_addr := inet_addr('127.0.0.1'); Addr.sin_port := HToNS(3320); FillChar(Addr.sin_zero, SizeOf(Addr.sin_zero), 0); if Connect(ServSock, Addr, SizeOf(TSockAddr)) = SOCKET_ERROR then ShowMessage('Îøèáêà'); vSize := sizeOf(BufSize); if getsockopt(ServSock,SOL_SOCKET,SO_RCVBUF,PChar(@BufSize),vSize) = SOCKET_ERROR then ShowMessage('Îøèáêà'); Memo1.Lines.Add(format('Receive buffer size [%d]',[BufSize])); SetLength(aBuf,BufSize); end; procedure TForm1.Button1Click(Sender: TObject); var buf : string; vSize: integer; vBuf : string; BufSize : integer; begin buf := Edit1.Text; if send(ServSock,buf[1],Length(buf),0) = SOCKET_ERROR then ShowMessage('Îøèáêà'); repeat vSize := recv(ServSock,aBuf[0],BufSize,0); if vSize <> 0 then Break; SetLength(vBuf,vSize); lstrcpyn(@vBuf[1],@aBuf[0],vSize + 1); Memo1.Lines.Add(format('Received from server: %s',[vBuf])); until vBuf = 'q'; end; procedure TForm1.FormDestroy(Sender: TObject); begin closesocket(ServSock); WSACleanup; end; end. Заранее спасибо за ответ. |