Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

Chat TCP w AutoIt by Phoenix_PL


Rekomendowane odpowiedzi

Opublikowano

Witam

 

Napisałem do szkoły taki powiedzmy w miarę porządnie napisany chat klient-serwer i chciałbym go udostępnić tutaj. Oczywiście można kopiować fragmenty kodu oraz się nimi posługiwać, przecież ten kod służy żeby się czegoś nauczyć.

 

Klient:

 

 

#include <GuiConstantsEx.au3>
#include <GUIEdit.au3>
TCPStartup()
 
Global $server
Global $ClientID
 
Opt ("GuiOnEventMode", 1)
 
#region GUI
;forma startowa
$form_start = GUICreate("Uruchamianie...", 206, 140)
$server_ip = GUICtrlCreateInput("IP Serwera", 8, 8, 193, 21)
$server_port = GUICtrlCreateInput("Port", 8, 40, 193, 21)
$user_id = GUICtrlCreateInput("ID", 8, 72, 193, 21)
$b_connect = GUICtrlCreateButton("Połącz", 64, 104, 75, 25)
GUISetOnEvent ($GUI_EVENT_CLOSE, "_knc_start")
GUICtrlSetOnEvent($b_connect, "polacz")
GUISetState(@SW_SHOW)
 
;gui klienta
$serverform = GUICreate("Klient", 626, 365)
$e_chat = GUICtrlCreateEdit("", 0, 0, 625, 329)
GUICtrlSetData(-1, "Wpisz /help żeby zobaczyć listę poleceń."&@CRLF)
$inmsg = GUICtrlCreateInput("", 0, 336, 625, 21, $ES_WANTRETURN)
GUISetOnEvent($GUI_EVENT_CLOSE, "_knc")
GUICtrlSetOnEvent($inmsg, "check_msg")
GUISetState(@SW_HIDE)
#endregion
 
Func _knc_start() ;wyjście
    Exit
EndFunc
 
Func _knc() ;wyjście + rozłączenie
    TCPSend($SERVER, "SERVERMSG_disconnect")
    TCPCloseSocket($SERVER)
    TCPShutdown()
    Exit
EndFunc
 
Func check_msg() ;wysłanie wiadomości na serwer
    Local $msg = GUICtrlRead($inmsg)
 
    Switch $msg
        Case "/help"
            writelog("------------"&@CRLF&"Lista komend:"&@CRLF& _
            "/exit - wyjście"&@CRLF& _
            "/stop - rozłączenie się z serwerem", 1)
        Case "/exit"
            _knc()
        Case "/stop"
            TCPSend($SERVER, "SERVERMSG_disconnect")
            TCPCloseSocket($SERVER)
            GUISetState(@SW_DISABLE, $serverform)
            GUISetState(@SW_SHOW, $form_start)
        Case Else
            TCPSend($SERVER, $ClientID&": "&$msg)
            writelog($ClientID&": "&$msg)
    EndSwitch
 
    GUICtrlSetData($inmsg, "")
EndFunc
 
Func writelog($text, $mode = 0) ;wypsanie wiadomości na chacie
    If $mode = 0 Then
        _GUICtrlEdit_AppendText($e_chat, "["&@HOUR&":"&@MIN&":"&@SEC&"] "&$text&@CRLF)
    Else
        _GUICtrlEdit_AppendText($e_chat, $text&@CRLF)
    EndIf
EndFunc
 
Func polacz() ;polaczenie z serwerem
    $ClientID = GUICtrlRead($user_id)
    If StringInStr($ClientID, " ") Then
        MsgBox(16, "Błąd!", "Niepoprawny nick!")
        Return
    EndIf
 
    ;pokazywanie okienka
    GUISetState(@SW_ENABLE, $serverform)
    GUISetState(@SW_HIDE, $form_start)
    GUISetState(@SW_SHOW, $serverform)
 
    ;pobranie danych z gui
    Local $IP = GUICtrlRead($server_ip)
    Local $Port = GUICtrlRead($server_port)
 
    ;obsługa localhost
    If $IP = "localhost" Then $IP = @IPAddress1
 
    ;połączenie
    $SERVER = TCPConnect($IP, $Port)
    ;writelog(@error)
    If @error Then
        MsgBox(16, "Błąd", "Nie mozna połączyć się z serwerem. Sprawdź IP oraz port.")
        GUISetState(@SW_DISABLE, $serverform)
        GUISetState(@SW_SHOW, $form_start)
        Return
    EndIf
 
    ;wysłanie serwerowi ID
    TCPSend($SERVER, $ClientID)
    Local $checknick
    Do
        $checknick = TCPRecv($SERVER, 128)
    Until $checknick <> ""
    If $checknick = "false" Then
        MsgBox(16, "Błąd", "Na serwerze jest juz ktos o takim ID")
        GUISetState(@SW_DISABLE, $serverform)
        GUISetState(@SW_SHOW, $form_start)
        Return
    EndIf
 
    ;adliby
    AdlibRegister("listen", 100)
    writelog("Połączono z serwerem. IP: "&$IP&":"&$Port)
    WinSetTitle($serverform, "Klient", "Klient - "&$ClientID)
EndFunc
 
Func listen() ;nasłuchiwanie wiadomości
    Local $recv = TCPRecv($SERVER, 1024)
    If $recv <> "" Then
        If StringLeft($recv, 10) = "SERVERMSG_" Then ;jeśli to wiadomość serwerowa
            $recv = StringReplace($recv, "SERVERMSG_", "")
            Switch $recv ;sprawdzanie komend
                Case "serverstop"
                    writelog("Serwer został wyłączony.")
                    TCPCloseSocket($SERVER)
                    GUISetState(@SW_DISABLE, $serverform)
                    GUISetState(@SW_SHOW, $form_start)
                Case "kicked"
                    writelog("Zostałeś wyrzucony z serwera!")
                    TCPCloseSocket($SERVER)
                    GUISetState(@SW_DISABLE, $serverform)
                    GUISetState(@SW_SHOW, $form_start)
            EndSwitch
        Else
            writelog($recv)
        EndIf
    EndIf
EndFunc
 
While 1
    Sleep (100)
WEnd

 

 

https://www.dropbox.com/s/mlbxwzapypgsfh0/klient.au3

 

Serwer:

 

 

#include <GuiConstantsEx.au3>
#include <GUIEdit.au3>
;#include <Array.au3>
TCPStartup()
 
Global $max_polaczonych = 50
Global $klienci[$max_polaczonych], $SERVER, $polaczeni = 0, $klienci_id[$max_polaczonych]
 
Opt ("GuiOnEventMode", 1)
 
#region GUI
;forma startowa
$form_start = GUICreate("Uruchamianie...", 206, 106)
$server_ip = GUICtrlCreateInput("IP Serwera", 8, 8, 193, 21)
$server_port = GUICtrlCreateInput("Port", 8, 40, 193, 21)
$b_runserver = GUICtrlCreateButton("Uruchom", 64, 72, 75, 25)
GUISetOnEvent ($GUI_EVENT_CLOSE, "_knc_start")
GUICtrlSetOnEvent($b_runserver, "start_server")
GUISetState(@SW_SHOW)
 
;gui serwera
$serverform = GUICreate("Serwer", 626, 365)
$e_chat = GUICtrlCreateEdit("", 0, 0, 625, 329)
GUICtrlSetData(-1, "Wpisz /help żeby zobaczyć listę poleceń."&@CRLF)
$inmsg = GUICtrlCreateInput("", 0, 336, 625, 21, $ES_WANTRETURN)
GUISetOnEvent($GUI_EVENT_CLOSE, "_knc")
GUICtrlSetOnEvent($inmsg, "check_msg")
GUISetState(@SW_HIDE)
#endregion
 
Func _knc_start() ;wyjście
    Exit
EndFunc
 
Func _knc() ;wyjście + rozłączenie
    If $polaczeni Then
        send_toall("SERVERMSG_serverstop")
        For $i = 0 To $polaczeni-1 Step +1
            TCPCloseSocket($klienci[$i])
        Next
    EndIf
 
    TCPCloseSocket($SERVER)
    TCPShutdown()
    Exit
EndFunc
 
Func writelog($text, $mode = 0) ;wypsanie wiadomości na chacie
    If $mode = 0 Then
        _GUICtrlEdit_AppendText($e_chat, "["&@HOUR&":"&@MIN&":"&@SEC&"] "&$text&@CRLF)
    Else
        _GUICtrlEdit_AppendText($e_chat, $text&@CRLF)
    EndIf
EndFunc
 
Func check_msg() ;sprawdza wiadomosc z inputa
    Local $msg = GUICtrlRead($inmsg)
    Switch $msg
        Case "/help"
            writelog("------------"&@CRLF&"Lista komend: "&@CRLF& _
            "/exit - wyjście"&@CRLF& _
            "/stop - wyłączenie serwera (pokazanie menu startowego)"&@CRLF& _
            "/list - lista połączonych klientów"&@CRLF& _
            "/kick [ID klienta] - rozłączenie danego klienta"&@CRLF& _
            "/pw [ID klienta] [wiadomość] - wysłanie prywatnej wiadomości do klienta", 1)
        Case "/exit"
            _knc()
        Case "/stop"
            stopserver()
        Case "/list"
            list()
        Case Else
            If StringLeft($msg, 5) = "/kick" Then
                Local $tmp = StringSplit($msg, " ")
                If $tmp[0] < 2 Then
                    writelog("Błąd -> Niepoprawna składnia polecenia.")
                    GUICtrlSetData($inmsg, "")
                    Return
                EndIf
 
                Local $nick = -1
                For $i = 0 To $polaczeni-1 Step +1
                    If $klienci_id[$i] = $tmp[2] Then
                        $nick = $i
                        ExitLoop
                    EndIf
                Next
 
                If $nick <> -1 Then
                    TCPSend($klienci[$nick], "SERVERMSG_kicked")
                    TCPCloseSocket($klienci[$nick])
                    writelog("Klient ID:"&$klienci_id[$nick]&" wyrzucony z serwera.")
                Else
                    writelog("Błąd -> Nie znaleziono klienta o takim nicku.")
                EndIf
            ElseIf StringLeft($msg, 3) = "/pw" Then
                Local $tmp = StringSplit($msg, " ")
                If $tmp[0] < 3 Then
                    writelog("Błąd -> Niepoprawna składnia polecenia.")
                    GUICtrlSetData($inmsg, "")
                    Return
                EndIf
 
                ;MsgBox(0, "test", UBound($tmp))
                For $a = 4 To $tmp[0] Step +1
                ;MsgBox(0, $a, $tmp[0]&@CRLF&$tmp[3]&@CRLF&$tmp[$a])
                    $tmp[3] &= " "&$tmp[$a]
                Next
 
                Local $client = -1
                For $i = 0 To $polaczeni-1 Step +1
                    If $klienci_id[$i] = $tmp[2] Then
                        $client = $i
                        ExitLoop
                    EndIf
                Next
 
                If $client <> -1 Then
                    TCPSend($klienci[$client], "[PW] Serwer -> "&$klienci_id[$client]&": "&$tmp[3])
                    writelog("[PW] Serwer -> "&$klienci_id[$client]&": "&$tmp[3])
                Else
                    writelog("Nie znaleziono klienta o podanym ID")
                EndIf
            Else
                send_toall("Serwer: "&$msg)
                writelog("Serwer: "&$msg)
            EndIf
    EndSwitch
 
    GUICtrlSetData($inmsg, "")
EndFunc
 
Func start_server() ;uruchamianie serwera
    ;pokazywanie okienka
    GUISetState(@SW_ENABLE, $serverform)
    GUISetState(@SW_HIDE, $form_start)
    GUISetState(@SW_SHOW, $serverform)
 
    ;pobranie danych z gui
    Local $IP = GUICtrlRead($server_ip)
    Local $Port = GUICtrlRead($server_port)
 
    ;obsługa localhost
    If $IP = "localhost" Then $IP = @IPAddress1
 
    ;połączenie
    $SERVER = TCPListen($IP, $Port)
    If @error Then
        writelog("Błąd -> Nie mozna uruchomić serwera. Sprawdź IP oraz port.")
        GUISetState(@SW_DISABLE, $serverform)
        GUISetState(@SW_SHOW, $form_start)
        Return
    EndIf
 
    ;adliby
    AdlibRegister("accept", 100)
    AdlibRegister("listen", 100)
    writelog("Serwer uruchomiony. IP: "&$IP&":"&$Port&@CRLF&"------------")
    WinSetTitle($serverform, "", "Serwer - "&$IP)
EndFunc
 
Func listen() ;nasłuchiwanie wiadomości
    Local $recv
    For $i = 0 To $polaczeni-1 Step +1 ;pętla odczytująca wiadomości od wszystkich klientów
        $recv = TCPRecv($klienci[$i], 1024)
        If $recv <> "" Then ;kiedy otrzyma wiadomość
            If StringLeft($recv, 10) = "SERVERMSG_" Then ;jeśli to wiadomość serwerowa
                $recv = StringReplace($recv, "SERVERMSG_", "")
                Switch $recv ;sprawdzanie komend
                    Case "disconnect"
                        TCPCloseSocket($klienci[$i])
                        $polaczeni -= 1
                        writelog("Klient (ID:"&$klienci_id[$i]&") został rozłączony.")
                        ;_ArrayDisplay($klienci)
                        ExitLoop
                EndSwitch
            Else
                For $a = 0 to $polaczeni-1 Step +1
                    If $a = $i Then ContinueLoop
                    TCPSend($klienci[$a], $recv)
                Next
                writelog($recv)
            EndIf
        EndIf
    Next
EndFunc
 
Func accept() ;akceptowanie klientów
    Local $client = TCPAccept($SERVER)
    If $client >= 0 and $polaczeni <> $max_polaczonych Then
        $klienci[$polaczeni] = $client
 
        ;czekanie na ID klienta
        Local $tempid
        Do
            $tempid = TCPRecv($client, 128)
        Until $tempid <> ""
 
        Local $testnick = True
        For $i = 0 To $polaczeni-1 Step +1
            If $tempid = $klienci_id[$i] Then
                $testnick = False
                ExitLoop
            EndIf
        Next
        If $testnick Then
            $klienci_id[$polaczeni] = $tempid
            TCPSend($client, "true")
        Else
            TCPSend($client, "false")
            Return
        EndIf
 
        $polaczeni += 1
        writelog("Klient się połączył, ID: "&$tempid)
        ;_ArrayDisplay($klienci)
    EndIf
EndFunc
 
Func send_toall($wiadomosc) ;wysłanie wiadomości do wszystkich klientów
    For $i = 0 To $polaczeni-1 Step +1
        TCPSend($klienci[$i], $wiadomosc)
    Next
EndFunc
 
Func stopserver() ;zatrzymanie serwera
    If $polaczeni Then
        For $i = 0 To $polaczeni-1 Step +1
            TCPSend($klienci[$i], "SERVERMSG_serverstop")
            TCPCloseSocket($klienci[$i])
        Next
    EndIf
 
    TCPCloseSocket($SERVER)
    writelog("Serwer wyłączony.")
    GUISetState(@SW_DISABLE, $serverform)
    GUISetState(@SW_SHOW, $form_start)
EndFunc
 
Func list() ;lista połączonych klientów
    writelog("------------"&@CRLF&"Ilość połączonych klientów/max: "&$polaczeni&"/"&$max_polaczonych, 1)
    writelog("Lista:", 1)
    For $i = 0 To $polaczeni-1 Step +1
        writelog($i+1&". "&$klienci_id[$i], 1)
    Next
EndFunc
 
While 1
    Sleep (100)
WEnd

 

 

https://www.dropbox.com/s/2i2otd8ajqotawr/serwer.au3

 

Feel free to edit!

846331404756772371599.jpeg
  • 1 miesiąc temu...
Opublikowano

Bardzo fajne :D Może i coś umiem w AutoIt, ale dla mnie to jest rewelka. Do poprawki przyda się zablokować $e_chat, bo można go edytować. Poza tym skrypt jest bardzo dobry, pierwszy raz nie było żadnego problemu z uruchomieniem, bo uruchomił się za pierwszym razem. Dodałbym jeszcze do clienta zapamiętywanie połączeń, czyli IP i port do pliku. Jeszcze znalazłem buga: Jak włączę serwer, potem clienta, w serwerze wpisze /kick mój_nick to wywala, ale nadal zostaje on w pamięci (można to sprawdzić /list)

 

Można skrypt sobie modyfikować na swoim komputerze? Oczywiście bez wrzucania na neta i zabieraniu praw autorskich.. Bo bym go zmodyfikował, dodał grafikę, nowe komendy itp :)

 

Dobra doczytałem koniec i można, więc zabieram się za edycję :D Ale jeszcze będzie nauki AutoIta.. Bo na razie nie mogę ogarnąć jak dodać nową komendę..

Od dnia 1.11.2013r. 14:17 zobaczono moje posty licznik-56-90712-stat.png razy ;)


 


 

  • 2 miesiące temu...
Opublikowano

Fajny program. Dodatkowo mam pytanie i chciałem się upewnić czy dobrze to robię. Gdy uruchamiam na jednym komputerze serwer i kilka klientów to używam localhost - wszystko dziala. A jeżeli chcę udostępnić komuś program to serwer i mój klient się nie zmienia a klient dla kogoś łączy się z moim ip np. odczytanym z internetu. Czy tak to ma wyglądać? Bo nie chce coś mi działać. Porty są ustawione te same we wszystkich programach. Dostaję informację aby sprawdzić IP. Pozdrawiam

  • 1 miesiąc temu...
  • 1 miesiąc temu...
Opublikowano

Phoenix twoje prace zawsze sa zajebiste, dzieki za wstawke.

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...