|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
Простейшая онлайн рисовалка для новичков через сокеты
Всегда тянуло к програмкам хоть как-то связанным с взаимодействием пользователей. Первое и самое простенькое, что решил написать, это чат на сокетах, погуглил, благо в интернете много гайдов по этой теме, написал. Чат был ужасно примитивным, поэтому, ради практики, решил немного увеличить его функционал, введя список пользователей, небольшой фильтр мата и тому прочее. Это всё делалось не ради чего-то высшего, а ради себя. И вот между тем решил еще чуть более усложнить программку и рядом с самим окном чата сделать небольшую стену, для общего рисования, где можно творить всем и сразу.
О том как сделать сам чат говорить не буду, т.к. а) В интернете очень много гайдов по этой теме б) Первая программа которую я написал на сокетах и был тот самый чат по тем самым гайдам, и оттого работа рисовалки очень схожа с работой чата. Программа будет с очень бедным функционалом, только окошко для рисования, никакого списка юзеров и т.п.. И так! Будем писать и сервер, и клиент, причем второй получился у меня более сложный по содержанию, поэтому начнём пожалуй с сервачка От сервера нам многое и не надо. Он всего-то и нужен нам для того, чтобы рассылать полученные координаты всем остальным юзверям, ну и естественно работал, поэтому из компонентов понадобится только две кнопки ( для запуска и остановки ), любая компонента для ввода порта, я взял TEdit, ну и сердце нашего сервера ServerSocket ( кидайте куда угодно, в готовой скомпилированной программе Вы его не увидите) . Естественно в коде можно забить один порт без права его ввода, но давайте лучше дадим свободы. Ну, с интерфейсом справились. Перейдем к самому коду. Тут писать много не надо. Запуск сервера осуществляется по такой процедуре. Код:
procedure TForm1.Button1Click(Sender: TObject); var port,err:integer; begin val(edit1.text,port,err); ServerSocket1.Port:=port; ServerSocket1.Active:=True; end; Код:
procedure TForm1.Button2Click(Sender: TObject); begin ServerSocket1.Active:=False; end; Не красота конечно, ну ладно, переживём. Первое что надо сделать это коннект: Код:
procedure TForm1.Button2Click(Sender: TObject); var port,err:integer; begin ClientSocket1.Host:=Edit1.text; val(edit2.text,port,err); ClientSocket1.Port:=port; ClientSocket1.Open; end; Код:
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin moused:=True; end; procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin moused:=False; end; procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var x1,y1:string; var send:string; begin if moused then begin str(x,x1); str(y,y1); send:=x1+' '+y1; ClientSocket1.Socket.SendText(send); end; end; Код:
procedure TForm1.ServerSocket1ClientWrite(Sender: TObject; Socket: TCustomWinSocket); var koordinati:string; var i:integer; begin koordinati:=Socket.ReceiveText; for i:=0 to ServerSocket1.Socket.ActiveConnections-1 do ServerSocket1.Socket.Connections[i].SendText(Socket.ReceiveText); end; Код:
procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket); var textik:string; x1,y1,i,err,j:integer; koor:string; begin textik:=Socket.ReceiveText; for i:=1 to length(textik) do begin if textik[i]<>' ' then koor:=koor+textik[i] else if textik[i]=' ' then begin val(koor,x1,err); break; end; end; koor:=''; for j:=i+1 to length(textik) do koor:=koor+textik[j]; val(koor,y1,err); Image1.Canvas.Pixels[x1,y1]:=clBlack end; И так, вроде бы всё готово, компилируем обе программы, запускаем сервер, вводим порт, жмем старт, запускаем клиент, вводим необходимые данные и коннектимся. Тадааам! http://justforfun27.livejournal.com/ Последний раз редактировалось Sn0wSky, 05.12.2011 в 19:58. |
#2
|
||||
|
||||
Я тут подумал, может лучше было сделать через массив?
Поясню: когда рисуешь (клиент), заносишь координаты в нейкий массив, а после того, как отпустил клавишу (или другой вариант - нажал на кнопку), этот массив передал на сервер. Вообщем, чтобы сеть не нагружать. Представь, линия из 100 пикселей = 100 сет. пакетов... Работа пpогpаммиста и шамана имеет очень много общего: оба боpмочyт непонятные слова, совеpшают непонятные действия и не могyт объяснить, как оно pаботает. |
#3
|
|||
|
|||
Цитата:
Хм, верно блин, просто моя голова пока плохо думает в плане оптимизации. Спасибо) |
#4
|
||||
|
||||
Зато при таком подходе будет рисоваться прямо "на ходу", то есть как один юзер мышь ведет, так и рисуется. Если же делать через массив, то пока чел не отпустит, никто ничего не увидит. А если он хочет в одно движение нарисовать какую-то фигуру длинную?
Думаю, хорошее решение как всегда где-то посередине: накапливать значения и по истечении какого-то времени передавать собранные данные. Тогда у пользователей будет рисоваться немного дерганнее, чем должно быть, но все же почти сразу, и нагрузка на сеть тоже будет поменьше. Время сбора данных можно варьировать, тем самым менять нагрузку, и опытным путем определить соотношение "нагрузка/скорость прорисовки у клиентов". Ну и разумеется, если пользователь отпустил мышу, то больше ждать нечего - надо отправлять то, что есть. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 05.12.2011 в 22:15. |
#5
|
|||
|
|||
Цитата:
Мне по поводу сокетов вот что интересно, есть какой-нибудь уникальный идентификатор у каждого клиента? Просто пока не придумал появилась идея самому раздавать номера и отправлять клиентам, чтобы там в переменную забивалось и сидела, при этом к каждому обращению к серверу еще и номер отправлять, но муторно как-то, в дельфи что-нибудь такое не предусмотрено? |
#6
|
||||
|
||||
Уникальный идентификатор есть - называется "IP + Port". =) Иначе как бы сервер знал, кому передавать данные? Вытаскиваешь из сокета IP и порт - вот тебе идентификатор. Правда клиент этих параметров может не знать (если он стоит за роутером). Но сервер будет знать и всегда уникально для каждого клиента.
jmp $ ; Happy End! The Cake Is A Lie. |