forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   BlitzMax (http://forum.boolean.name/forumdisplay.php?f=104)
-   -   Вопрос-Ответ (для новичков BlitzMax) (http://forum.boolean.name/showthread.php?t=13756)

Randomize 19.11.2014 00:58

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Jlemyp (Сообщение 289503)
...

Смотри стандартный пример:
BlitzMax\samples\mak\gnetchat.bmx
И в этой же папке:
BlitzMax\samples\mak\gnetdemo.bmx
Второй особенно интересен. Код немного сложноват, но для экспериментов пойдёт.
В примерах используется стандартная библиотека gnet, она не очень производительна, но для простеньких игр и экспериментов подходит замечательно.

Arton 19.11.2014 02:11

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Jlemyp (Сообщение 289503)
Нет описания на русском операторов связаных с сетью,что бы понять что за что отвечает.

Справочник по BlitzMax

Jlemyp 20.11.2014 23:50

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Мне стыдно,но я полный нуль в этом.Почему не подключается клиент к серверу
сервер:
Strict
Import BRL.GNet
Global port=50000
Global host:TGNetHost=CreateGNetHost:TGNetHost()
GNetListen( host,port )

While Not KeyHit( KEY_ESCAPE )

Wend

клиент:
Import BRL.GNet
Global port=50000
SeedRnd MilliSecs()
Global host:TGNetHost=CreateGNetHost:TGNetHost()
f=GNetConnect(host,"127.0.0.1",port)
Print f

подскажите направление моей тупости.

Jlemyp 21.11.2014 12:12

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
пожалуйста,напишите в 5 строчках создание серва и создание клиента.Как узнать полключился клиент к серву или нет?

Randomize 21.11.2014 12:25

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
GNetSync(host) в цикле сервера.
Эта ф-ция - обработчик сервера. Если её не вызывать он и работать не будет.
Не забывай после работы закрывать соединения!
Иначе можно получить кучу багов из-за открытых остаточных соединений (см. порт занят).

Jlemyp 21.11.2014 14:46

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Огромное спасибо!!! С GNetSync(host) клиент сразу подключился.Я немного буду задавать глупые для Вас вопросы,но хотел бы получать взамен полезные ответы для себя.

Randomize 21.11.2014 16:53

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Jlemyp (Сообщение 289578)
Я немного буду задавать глупые для Вас вопросы,но хотел бы получать взамен полезные ответы для себя.

Без проблем. Обращайся. Мы тут для того и сидим.

Jlemyp 21.11.2014 21:52

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Подключится,подключился,но передать данные зи клиента на сервер неполучается.Подскажите какую команду еще забыл..
сервер:
Import BRL.GNet
Global port=50000
SeedRnd MilliSecs()
Global host:TGNetHost=CreateGNetHost:TGNetHost()
Global me:TGNetObject=CreateGNetObject:TGNetObject(host)
GNetListen( host,port )

While Not KeyHit( KEY_ESCAPE )
GNetSync(host)
If Not me Print GetGNetString$(me,0)
Wend

CloseGNetHost (host)

клиент :
Import BRL.GNet
Global port=50000
Global add$="127.0.0.1"
Global host:TGNetHost=CreateGNetHost:TGNetHost()
Global me:TGNetObject=CreateGNetObject:TGNetObject( host )

If GNetConnect(host,add,port)
SetGNetString (me,0,"Ready")
EndIf

CloseGNetHost (host)

Randomize 22.11.2014 11:02

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Cообщения, что на сервере, что на клиенте обрабатываем так:
Код:

For Local obj:TGNetObject=EachIn GNetObjects( host )
        If obj.State()=GNET_CLOSED Continue ' Закрытые сообщения не нужны
        Print GetGNetString( obj, 0)
Next

Рекомендую ещё раз изучить примеры из стандартной поставки BlitzMax.
Цитата:

Сообщение от Randomize (Сообщение 289506)
Смотри стандартный пример:
BlitzMax\samples\mak\gnetdemo.bmx


Jlemyp 22.11.2014 15:07

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
как правильно понять эту ошибку - Unhandled Exception: Assert failed
необработанное исключение ? Это вылетает когда обрабатываю сообщения на сервере.

Jlemyp 22.11.2014 23:19

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
провел 5 часов не вставая из-за компа,выпил 3 бокала чая,но так и не смог передать от клиента серверу данные.Пробывал понять как устроен на сокетах сервер и тоже упирался в тупик.Не хочу на Blitz3d там 2d графика плохо реализованна, а Fastimage с ключем нет.Хочу понять здесь сеть,но нервы начинают сдавать.

Жека 27.11.2014 09:00

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Вложений: 2
Я когда-то делал простенький клиент-сервер на максе, на основе TCP.

Суть:
1. клиенты представляют из себя движущиеся объекты (в пределах экрана)
2. сервер должен следить за перемещениями этих объектов, отображая всех на экране

Данные от клиентов передаются 1 раз в секунду, можно изменить "timeSendPosInterval = 1000".

Клиенты могут отправлять текстовую инфу серверу, она отобразится в поле "info".

Подключение происходит на локальный адрес, можно изменить: "remoteIp = HostIp("127.0.0.1")".

По умолчанию порт для подключения 50000, при наличии файла port.txt в корне с exe-шниками - порт загружается оттуда.

Примечание: для получения русских символов есть простецкий конвертер в файле utils.bmx.

Запуск:
1. запустить tcpServer
2. запустить tcpClient один или несколько раз

tcpClient.bmx
Код:

SuperStrict

Include "utils.bmx"

AppTitle = "tcpServer"



Global maxLines:Int = 20

Global strTmp:String = ""

Global info:String


Graphics 800, 600

SetImageFont(LoadImageFont("arial.ttf", 12))

Local port:Int = 50000
If(FileType("port.txt") = 1)
        port = Int(LoadText("port.txt"))
EndIf

Global server:TServer = New TServer
server.start(port)

Local char:Short


While Not(KeyHit(KEY_ESCAPE) Or AppTerminate())

        server.update()
       
        char = GetChar()
        If(char <> 0) Then server.sendToAll(Chr(char))
       
        DrawText("Port: " + port + ", online: " + server.onlineCount, 20, 50)
        DrawText("Info: " + info, 20, 70)
       
        server.drawPos()
       
        Flip()
        Cls()
       
Wend

server.stop()

End


Function socketSend(sock:TSocket, text:String)
       
        text:+"~r~n"
        sock.Send(text, Len(text))
        DebugLog("send: " + text)
       
End Function


Function socketRecv:String(sock:TSocket, bufData:Byte[], bufSize:Int)
       
        If(sock.ReadAvail() = 0) Then Return Null
       
        strTmp = ""
        Local size:Int = 0
       
        While(sock.ReadAvail() > 0)
                flushBuf(bufData, bufSize)
                size = sock.ReadAvail()
                If(size > bufSize) size = bufSize
                sock.Recv(bufData, size)
                strTmp:+String.FromCString(bufData).Trim()
        Wend
       
        strTmp = convertFromAnsi(strTmp)
               
        Return strTmp
       
End Function



Type TServer
        Field socket:TSocket
        Field connect:TSocket

        Const bufSize:Int = 255
        Field bufData:Byte[] = New Byte[bufSize]
        Field bufStr:String[] = Null

        Field listMsg:TList = New TList

        Field listClients:TList = New TList
       
        Field cmd:String
       
        Field onlineCount:Int
       
       
       
        'запуск
        Method start(port:Int = 5000)
                socket = CreateTCPSocket()
                BindSocket(socket, port)
                SocketListen(socket)
        End Method

       
        'остановка
        Method stop()
                CloseSocket(socket)
        End Method


        'добавление нового клиента в список
        Method clientAdd:TClient(socket:TSocket)
                Local cli:TClient = New TClient
                cli.socket = socket
                listClients.addLast(cli)
                onlineCount:+1
                Return cli
        End Method
       
       
        'удаление клиента из списка
        Method clientRemove(client:TClient)
                listClients.Remove(client)
                onlineCount:-1
                DebugLog("disconnect " + client.getId() + " at " + CurrentTime())
        End Method
       
       
        'обработка клиентов
        Method update()
       
                'подключение новых клиентов
                If(connect = Null)
                        connect = SocketAccept(socket)
                        If(connect <> Null)
                                clientAdd(connect)
                                socketSend(connect, "ID")
                                connect = Null
                        EndIf
                EndIf
               
       
                'прослушивание клиентских сокетов
                If(listClients.IsEmpty()) Return
               
                Local params:String[]
               
                For Local cli:TClient = EachIn listClients
                       
                        'клиент отключился
                        If(cli.socket.Connected() = False)
                                clientRemove(cli)
                                Continue
                        EndIf
                       
                        'получение и обработка данных
                        strTmp = socketRecv(cli.socket, bufData, bufSize)
                        If(strTmp <> "")
                                bufStr = strTmp.Split("~r~n")
                                For Local k:Int = 0 Until bufStr.Length
                                        cmd = bufStr[k].Trim()
                                        If(cmd = "") Continue
                                        'разделение на параметры
                                        params = commandParseCommand(cli, cmd)
                                        'выполнение
                                        commandProcessCommand(cli, params)
                                        'добавление в чат
                                        strTmp = cli.getId() + ": " + cmd
                                        listMsg.AddLast(strTmp)
                                        If(listMsg.Count() > maxLines) Then listMsg.Remove(listMsg.First())
                                        DebugLog(strTmp)
                                Next
                        EndIf
                Next
       
        End Method
       
       
        'разбор команды
        Method commandParseCommand:String[] (client:TClient, cmd:String)
                Local mas:String[] = cmd.Split(" ")
                Return mas
        End Method
       
       
        'выполнение команд
        Method commandProcessCommand(client:TClient, params:String[])
                Local cmd:String = params[0]
                If(cmd = "ID")
                        client.setId(Int(params[1]))
                Else If(cmd = "POS")
                        client.setPos(Int(params[1]), Int(params[2]))
                Else
                        info = cmd
                EndIf
        End Method
       
       
        'массовая рассылка всем, кроме указанного
        Method sendToOther(client:TClient, text:String)
                If(listClients.IsEmpty()) Then Return
       
                For Local cli:TClient = EachIn listClients
                        If(cli <> client)
                                socketSend(cli.socket, text)
                        EndIf
                Next
               
        End Method
       
        'массовая рассылка всем, кроме указанного
        Method sendToAll(text:String)
                sendToOther(Null, text)
        End Method
       
        'рисование позиций на карте
        Method drawPos()
                If(listClients.IsEmpty()) Then Return
                Local px:Int, py:Int, sz:Int = 20
                Local name:String
               
                For Local cli:TClient = EachIn listClients
                        px = cli.getX()
                        py = cli.getY()
                       
                        cli.adjustColor()
                        DrawRect(px, py, sz, sz)
                       
                        SetColor(200, 200, 200)
                        name = "" + cli.getId()
                        DrawText(name, px - (TextWidth(name) - sz) * 0.5, py - 17)
                Next
               
        End Method
       
End Type


Type TClient
        Field socket:TSocket
        Field obj:TObj = New TObj
       
        Field red:Int, green:Int, blue:Int
       
       
        Method setId(id:Int)
                obj.id = id
                red = Rand(100, 255)
                green = Rand(100, 255)
                blue = Rand(100, 255)
        End Method
       
        Method adjustColor()
                SetColor(red, green, blue)
        End Method
       
        Method getId:Int()
                Return obj.id
        End Method
       
        Method setPos(x:Int, y:Int)
                obj.x = x
                obj.y = y
        End Method
       
        Method getX:Int()
                Return obj.x
        End Method
       
        Method getY:Int()
                Return obj.y
        End Method
       
End Type


Type TObj
        Field name:String
        Field id:Int
        Field x:Int, y:Int
End Type



tcpClient.bmx
Код:

SuperStrict

SeedRnd(MilliSecs())

AppTitle = "tcpClient"

Include "utils.bmx"

Local remotePort:Int = 50000
If(FileType("port.txt") = 1)
        remotePort = Int(LoadText("port.txt"))
EndIf
Local remoteIp:Int = HostIp("127.0.0.1")

Global cliSocket:TSocket = CreateTCPSocket()
ConnectSocket(cliSocket, remoteIp, remotePort)

Global bufSize:Int = 255
Global bufData:Byte[] = New Byte[bufSize]

Global bufStr:String[] = Null

Global listMsg:TList = New TList

Global maxLines:Int = 20

Global screenW:Int = 800
Global screenH:Int = 600

Graphics screenW, screenH
SetImageFont(LoadImageFont("arial.ttf", 16))
 
Global text:String
Global strTmp:String

text = ""

Global ch:Int = 0

Global onConnect:Int = True

Global posX:Float, posY:Float, spdX:Float, spdY:Float
Global timeMoveStart:Int, timeMoveInterval:Int = 100

posX = Rand(screenW)
posY = Rand(screenH)
spdX = Rnd(-1, 1)
spdY = Rnd(-1, 1)

Global timeSendPosStart:Int, timeSendPosInterval:Int = 1000


If(Not(SocketConnected(cliSocket)))
        DrawText "Server is not run. Try to connecting later.", 20, 20
        DrawText "Press any key to exit.", 40, 50
        WaitKey()
        End
EndIf

Local rez:Int = False

Global onRunning:Int = True


While(onRunning = True)
       
        If(KeyHit(KEY_ESCAPE) Or AppTerminate())
                onRunning = False
                Exit
        EndIf
       
       
        drawMessages()
               
        SetColor 155, 155, 155
        DrawLine 10, 10, screenW - 10, 10
        DrawLine 10, screenH - 50, screenW - 10, screenH - 50
        DrawLine 10, screenH - 10, screenW - 10, screenH - 10
       
        SetColor 255, 255, 255
        DrawText "> " + text, 10, screenH - 40
       
        If(MilliSecs() Mod 1000 < 500)
                DrawRect 10 + TextWidth("> " + text) + 2, screenH - 40, 2, 20
        EndIf
       
        DrawRect(posX, posY, 20, 20)
       
        Flip()
        Cls()
       
        rez = checkInput()
       
        If(rez = True) 'нажали Enter
                send(text)
                text = ""
        EndIf
       
        recv()
       
        If(Not(SocketConnected(cliSocket)))
                Exit
        EndIf
       
        moveObject()
       
        If(MilliSecs() - timeSendPosStart >= timeSendPosInterval)
                send("POS " + Int(posX) + " " + Int(posY))
                timeSendPosStart = MilliSecs()
        EndIf
       
Wend


CloseSocket(cliSocket)
 
End



Function moveObject()
        If(MilliSecs() - timeMoveStart < timeMoveInterval) Then Return
       
        posX:+spdX * 3
        posY:+spdY * 3
       
        If((posX <= 0 And spdX < 0) Or (posX >= screenW And spdX > 0))
                spdX:*- 1
        EndIf
        If((posY <= 0 And spdY < 0) Or (posY >= screenH And spdY > 0))
                spdY:*- 1
        EndIf
       
        If(Rand(100) < 5)
                spdX = Rnd(-1, 1)
                spdY = Rnd(-1, 1)
        EndIf
       
        timeMoveStart = MilliSecs()
End Function


Function drawMessages(x0:Int = 20, y0:Int = 20)
       
        If(listMsg.IsEmpty()) Then Return
       
        Local px:Int = x0, py:Int = y0
        For Local k:Int = 0 Until listMsg.count()
                px = x0
                strTmp = String(listMsg.ValueAtIndex(k))
                If(Mid(strTmp, 1, 2) = "я:")
                        SetColor 255, 255, 0
                ElseIf(Mid(strTmp, 1, 7) = "сервер:")
                        SetColor 255, 0, 0
                        'px:+5
                Else
                        SetColor 255, 255, 255
                EndIf
                DrawText strTmp, px, py
                py:+20
        Next

End Function


Function checkInput:Int()
        ch = GetChar()
        If(ch <> 0)
                text = text + Chr(ch)
                If(ch <> 32) text = text.Trim()
               
                If(ch = 8) 'backspace
                        If(Len(text) > 0)
                                text = Left(text, Len(text) - 1)
                        EndIf
                EndIf
        EndIf
       
        If(ch = 13)
                Return True
        Else
                Return False
        EndIf
End Function


Function send(msg:String)
               
        listMsg.AddLast("я: " + MSG)
        If(listMsg.Count() > maxLines) Then listMsg.Remove(listMsg.First())
        msg:+"~r~n"
        cliSocket.send(msg, Len(msg))
       
End Function


Function recv()
        If(cliSocket.ReadAvail() = 0) Then Return
       
        strTmp = ""
       
        While(cliSocket.ReadAvail() > 0)
                flushBuf(bufData, bufSize)
                cliSocket.Recv(bufData, bufSize)
                strTmp:+String.FromCString(bufData).Trim()
        Wend
       
        strTmp = convertFromAnsi(strTmp)
       
        bufStr = strTmp.Split(Chr(10))
        For Local k:Int = 0 Until bufStr.Length
                If(bufStr[k].Trim() = "") Then Continue
                listMsg.AddLast(bufStr[k].Trim())
                If(listMsg.Count() > maxLines) Then listMsg.Remove(listMsg.First())
        Next

        'разбор команды
        If(strTmp = "ID")
                text = "ID " + String(Rand(1000000))
                send(text)
        Else If(strTmp = "QUIT")
                onRunning = False
        EndIf
       
End Function



utils.bmx
Код:

Function flushBuf(buf:Byte Ptr, size:Int)
        For Local k:Int = 0 Until size
                buf[k] = 0
        Next
End Function


Function convertToAnsi:String(text:String)
        Local str:String = ""
        Local count:Int = Len(text)
        For Local k:Int = 0 Until count
                If(text[k] >= 1040 And text[k] <= 1103)
                        str:+Chr(text[k] - 1040 + 192)
                ElseIf(text[k] = 1025) 'Ё
                        str:+Chr(168)
                ElseIf(text[k] = 1105) 'ё
                        str:+Chr(184)
                Else
                        str:+Chr(text[k])
                EndIf
        Next
        Return str
End Function


Function convertFromAnsi:String(text:String)
        Local str:String = ""
        Local count:Int = Len(text)
        For Local k:Int = 0 Until count
                If(text[k] >= 192 And text[k] <= 255)
                        str:+Chr(text[k] - 192 + 1040)
                ElseIf(text[k] = 168) 'Ё
                        str:+Chr(1025)
                ElseIf(text[k] = 184) 'ё
                        str:+Chr(1105)
                Else
                        str:+Chr(text[k])
                EndIf
        Next
        Return str
End Function



Прилагаю код и скомпиленные файлы.

ПС: Возможно, стоит оформить этот пост в раздел "FAQ и уроки".

Jlemyp 27.11.2014 10:13

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Твой урок у меня уже есть и я его разбирал.Но возникали проблемы,все равно сервер не получает значения.Вопрос: Сервер обязательно должен быть сделан на основе Типов? Мне главное понять работу сокетов.Другой вопрос,как запустить несколько клиентов на одной машине?При запуске 2 клиента пишет ошибка и не запускается.

Жека 27.11.2014 12:53

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Клиент должен знать ip адрес сервера и порт. Ошибка в клиенте будет только если сервер не запущен.
Какая конкретно ошибка возникает?
Кинь весь код, посмотрю.

Черный крыс 30.11.2014 03:08

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
www.blitzforum.de/forum/viewtopic.php?t=8988

http://www.blitzforum.de/forum/viewtopic.php?t=9063

http://www.blitzforum.de/forum/viewtopic.php?t=12162

moka 01.12.2014 20:30

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Как урок нормально, но в будущем на заметку: сервер не должен заниматься рендерингом вообще, а только логикой и обменом данных, когда рендерингом заниматься должны клиенты.

Sashkakuhta 05.01.2015 14:03

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
На гитхабе в bmx-ng (https://github.com/bmx-ng) сейчас наблюдается копошение, и судя по всему они там сделали возможность компиляции blitzmax кода под андроид и rasberry pi. Никто не заглядывал туда? Я слишком криворук, чтобы проверить все сам...

Жека 15.02.2015 13:50

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Вопрос по maxgui.

Есть форма, к ней привязан канвас. Я рисую в канвас, но ничего не вижу.
Главный цикл построен на бесконечном цикле с ожиданием событий и последующим разгребанием событий.

Ещё такая фишка - при нажатии на кнопку ставится флаг "перерисовать канвас", и всё ок - перерисовывается.
Если же я в событии EVENT_WINDOWSIZE ставлю этот флаг, то нифига - чёрный экран. чё за хрень такая понять не могу.

Flip в конце цикла стоит.

UPD: проблему решил флаг у флипа - Flip(0), с дефолтным -1 были глюки.

Delmar 13.03.2015 15:37

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
У меня простой вопрос.
Начал не давно изучать BlitzMax и столкнулся вот с какой проблемой.
Я создал окно и пару кнопок используя MaxGui, и не как не могу найти что нужно сделать чтобы проверить нажата ли кнопка или нет, для того чтобы запустить какое нибудь событие. Если не сложно не могли бы вы скинуть простой пример кода: Окно плюс пару кнопок и проверка на нажатие.

P.S. Вопрос закрыт разобрался.

edgemza 08.10.2016 16:15

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от Arton (Сообщение 289508)

Ох "засада"... уже эти ссылки не работают :(
А ведь наверно полезные сайты были?!

Arton 09.10.2016 00:31

Ответ: Вопрос-Ответ (для новичков BlitzMax)
 
Цитата:

Сообщение от edgemza (Сообщение 309079)
Ох "засада"... уже эти ссылки не работают :(

Потому что старое никому не нужно, от всего старого надо избавляться, выбрасывать на свалку истории. Надо творить новое, старое только мешает этому. А потом новое становится старым и его тоже жизненно необходимо выбросить. Такова жизнь!
Понятно, мой юный булчанин?


Цитата:

Сообщение от edgemza (Сообщение 309079)
А ведь наверно полезные сайты были?!

Вполне.


Часовой пояс GMT +4, время: 11:58.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot