|
#1
|
|||
|
|||
Чат на сокетах
Здрасьте
Знаю, что тема до невозможности бородатая, но возникла необходимость создания программы для чата, и при ее создании возникли некоторые сложности. А именно - не приходят сообщения от клиента к серверу. От сервера идут, а обратно не хотят. Клиент и сервер реализованы в одной программе. Вот код: Код:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ScktComp; type TForm1 = class(TForm) ClientSocket: TClientSocket; ServerSocket: TServerSocket; portedit: TEdit; lblport: TLabel; IP: TLabel; Hostedit: TEdit; Nik: TLabel; NikEdit: TEdit; txtlbl: TLabel; TextEdit: TEdit; ChatMemo: TMemo; SendBtn: TButton; ServerBtn: TButton; ClientBtn: TButton; procedure FormCreate(Sender: TObject); procedure ServerBtnClick(Sender: TObject); procedure ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); procedure SendBtnClick(Sender: TObject); procedure ClientBtnClick(Sender: TObject); procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocketDisconnect(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocketAccept(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocketConnecting(Sender: TObject; Socket: TCustomWinSocket); procedure ServerSocketClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} //ЗАПОЛНЕНИЕ ПОЛЕЙ procedure TForm1.FormCreate(Sender: TObject); begin PortEdit.Text:='50000'; HostEdit.Text:='192.168.0.100'; NikEdit.Clear; TextEdit.Clear; ChatMemo.Lines.Clear; end; //СЕРВЕР procedure TForm1.ServerBtnClick(Sender: TObject); begin If ServerBtn.Tag=0 then Begin ClientBtn.Enabled:=False; HostEdit.Enabled:=False; PortEdit.Enabled:=False; ServerSocket.Port:=StrToInt(PortEdit.Text); ServerSocket.Active:=True; ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер создан'); ServerBtn.Tag:=1; ServerBtn.Caption:='Закрыть сервер'; end else Begin ClientBtn.Enabled:=True; HostEdit.Enabled:=True; PortEdit.Enabled:=True; ServerSocket.Active:=False; ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сервер закрыт.'); ServerBtn.Tag:=0; ServerBtn.Caption:='Создать сервер'; end; end; procedure TForm1.ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add(Socket.ReceiveText); end; procedure TForm1.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключился клиент.'); end; procedure TForm1.ServerSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Клиент отключился.'); end; procedure TForm1.ServerSocketAccept(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключился клиент.'); end; procedure TForm1.ServerSocketClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Ошибка.'); end; //КЛИЕНТ procedure TForm1.ClientBtnClick(Sender: TObject); begin If ClientBtn.Tag=0 then Begin ServerBtn.Enabled:=False; HostEdit.Enabled:=False; PortEdit.Enabled:=False; ClientSocket.Port:=StrToInt(PortEdit.Text); ClientSocket.Host:=HostEdit.Text; ClientSocket.Address:=HostEdit.Text; ClientSocket.Active:=True; ClientBtn.Tag:=1; ClientBtn.Caption:='Отключиться'; end else Begin ServerBtn.Enabled:=True; HostEdit.Enabled:=True; PortEdit.Enabled:=True; ClientSocket.Active:=False; ClientBtn.Tag:=0; ClientBtn.Caption:='Подключиться'; end; end; procedure TForm1.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add(Socket.ReceiveText); end; procedure TForm1.ClientSocketConnecting(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Подключение к серверу.'); end; procedure TForm1.ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Успешно.'); end; procedure TForm1.ClientSocketDisconnect(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add('['+TimeToStr(Time)+'] Сеанс завершен.'); end; //ОТПРАВКА СООБЩЕНИЯ procedure TForm1.SendBtnClick(Sender: TObject); begin If ServerSocket.Active=True then begin ServerSocket.Socket.Connections[0].SendText('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+''); end else begin ClientSocket.Socket.SendText('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+''); end; ChatMemo.Lines.Add('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+''); TextEdit.Text:=''; end; end. Предполагаю, что проблема кроется либо здесь: Код:
procedure TForm1.ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add(Socket.ReceiveText); end; либо тут: Код:
//ОТПРАВКА СООБЩЕНИЯ procedure TForm1.SendBtnClick(Sender: TObject); begin If ServerSocket.Active=True then begin ServerSocket.Socket.Connections[0].SendText('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+''); end else begin ClientSocket.Socket.SendText('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+''); end; ChatMemo.Lines.Add('['+TimeToStr(Time)+'] '+NikEdit.Text+': '+TextEdit.Text+''); TextEdit.Text:=''; end; Ах да.. я тут новичок. Да и в программировании тоже тот еще ламер. Так что прошу сильно не ругать |
#2
|
||||
|
||||
Так в демках есть пример чата NetChat.
Пишу программы за еду. __________________ |
#3
|
|||
|
|||
как это клиент и сервер в одной программе??
я писал на работе чат на сокетах Но! Сервер отдельная тема Клиент так же Если надо могу через пару часов выложить тебе свой исходник |
#4
|
||||
|
||||
Да, в демке сервер и клиент в одной куче. Но мы же программисты и можем без проблем разделить их)
Пишу программы за еду. __________________ |
#5
|
|||
|
|||
не проще тогда уж писать на мультикасте этот самый чат ?)
Ну а если на клиент/сервер сокетах - то с отдельным сервером ?) Последний раз редактировалось ApxaHGe1, 02.09.2016 в 12:06. |
#6
|
||||
|
||||
Цитата:
Суть в том, что «абонент» может являться одновременно клиентом и сервером. Яркий пример — bittorrent: http://www.delphisources.ru/forum/sh...63&postcount=1 (написано на дельфи). Таким же макаром невозбраняется и текст передавать. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#7
|
|||
|
|||
Этим ярким примером, я пользуюсь )) ничего лишнего в нем потому что нет,
ДА и спасибо автору, т.е. тебе ) Да знакомо, но я бы все равно сделал тогда уж на Broadcast-е c UDP |
#8
|
||||
|
||||
Цитата:
------- Спасибо за тёплые слова по поводу Лайма — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#9
|
|||
|
|||
Цитата:
ApxaHGe1, хотелось бы с сокетами именно разобраться. Ведь почти добил их. M.A.D.M.A.N., так точно - одноранговая сеть. Но почему не работает?.. Могу скинуть проект весь, если нужно. |
#10
|
||||
|
||||
Честно говоря, сложно разобраться в твоем коде, ибо он неотформатирован.
Вообще, я бы советовал передавать сокет в ф-ю обработки пакетов, нежели делать отдельный код под сервер. — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#11
|
|||
|
|||
Цитата:
Можно поподробнее? |
#12
|
|||
|
|||
Поможет кто-нибудь?..
|
#13
|
||||
|
||||
Так был бы конкретный вопрос...
Пишу программы за еду. __________________ |
#14
|
|||
|
|||
Цитата:
Вопрос: почему сервер не получает сообщение от клиента. И достаточно ли этого на стороне сервера: Код:
procedure TForm1.ServerSocketClientRead(Sender: TObject; Socket: TCustomWinSocket); begin ChatMemo.Lines.Add(Socket.ReceiveText); end; |
#15
|
||||
|
||||
Да, этого вполне достаточно. Только что ещё раз проверил. Вообще простейший чат состоит из 4-х !!! руками написаных строчек кода. Остальное пишет Delphi. Где там можно ошибиться я просто не представляю.
Пишу программы за еду. __________________ |