Jump to content

UDP Multi User Client+Server


Blinky
 Share

Recommended Posts

Here is my first post.

A UDP soket based chat.Multiple clients. No gui server.

It`s verry fast writen and it needs function protection and it has a lot of bugs but it works just fine like this.

This is a perfect example for beginers. i hope i can post more tiny scripts that help beginers

Can be added:

-private msg

-unique and not nul login name

-password

-better gui

-friends list

-offline mssg

- latency to server

....and so on

i know how to do all of this but I`m to lazy to perfect it.

Server(run first)

#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)
Global $socket[21], $socketR, $id = ""
Global $user[21][4]
$i = 0
Do
$i = $i + 1
For $j = 1 To 20
  $user[$j][$i] = ""
  $socket[$j] = ""
Next
Until $i = 3

UDPStartup()
OnAutoItExitRegister("Cleanup")
$socketR = UDPBind("127.0.0.1", 65533)
If @error Then Exit

While 1
$sdata = UDPRecv($socketR, 200)
If $sdata <> "" Then
  $rData = StringSplit($sdata, " ")
  If $rData[1] = "login" Then
   For $i = 1 To 20
    If $user[$i][1] = "" Then
     $id = $i
     ExitLoop
    EndIf
   Next
   $socket[$id] = UDPOpen($rData[2], $rData[4])
   $user[$id][1] = $rData[3]
   $user[$id][2] = $rData[2]
   $user[$id][3] = $rData[4]
   update($id, 1)
  Else
   If $rData[1] = "logout" Then
    $id = $rData[2]
    $user[$id][1] = ""
    update($id, 0)
   Else
    For $i = 1 To 20
     If $user[$i][1] <> "" Then $status = UDPSend($socket[$i], $sdata)
    Next
   EndIf
  EndIf
EndIf
Sleep(1)
If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
WEnd
Func update($var1, $var2)
$userData = "update"
For $i = 1 To 20
  If $user[$i][1] <> "" Then $userData = String($userData & " " & $user[$i][1])
Next
For $i = 1 To 20
  If $user[$i][1] <> "" Then
   UDPSend($socket[$i], $userData)
   If $var2 = 1 Then UDPSend($socket[$i], $user[$var1][1] & "--- Joined The Chanel")
   If $var2 = 0 Then UDPSend($socket[$i], $user[$var1][1] & "--- Left The Chanel")
  EndIf
Next
If $var2 = 1 Then UDPSend($socket[$var1], "id " & $var1)
If $var2 = 0 Then UDPCloseSocket($socket[$var1])
EndFunc
Func Cleanup()
UDPCloseSocket($socketR)
UDPShutdown()
EndFunc

The server can be closed from Tray

Client:

#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiButton.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>

Opt("GUIOnEventMode", 1)
HotKeySet("{esc}", "quit")
Global $socketS, $socketR, $sName, $chatBox, $input, $sendB, $LoginButon, $userList, $id, $var12

UDPStartup()
OnAutoItExitRegister("Cleanup")
$gui = GUICreate("Chat", 600, 500)
$chatBox = GUICtrlCreateEdit("", 10, 10, 490, 440, $ES_READONLY)
$sendB = GUICtrlCreateButton("Send", 10, 460, 50, 20, $BS_DEFPUSHBUTTON)
GUICtrlSetOnEvent($sendB, "SendMsg")
$input = GUICtrlCreateInput("", 70, 460, 370, 20)
$LogOutB = GUICtrlCreateButton("LogOut", 530, 460, 50, 20)
GUICtrlSetOnEvent($LogOutB, "logout")
$userList = _GUICtrlListView_Create($gui, "Users", 510, 10, 80, 440, $LVS_NOCOLUMNHEADER)
_GUICtrlListView_SetColumnWidth($userList, 1, 85)

$lgui = GUICreate("Login", 100, 200, -1, -1, -1, -1, $gui)
$LoginButon = GUICtrlCreateButton("Login", 10, 75, 80, 20, $BS_DEFPUSHBUTTON)
GUICtrlSetOnEvent($LoginButon, "login")
$LoginInput = GUICtrlCreateInput("", 10, 45, 80, 20)
GUICtrlCreateLabel("Pls Write Your Name To Login", 10, 5, 80, 40)
$IpInput = GUICtrlCreateInput("127.0.0.1", 10, 105, 80, 20)
GUICtrlCreateLabel("Server Ip", 10, 135, 80, 40)
GUISetState(@SW_SHOW, $lgui)
Func login()
;recive
$port = Random(60000, 65532, 1)
$ip = "127.0.0.1"
$socketR = UDPBind($ip, $port)
If @error <> 0 Then Exit
;send
$sIp = GUICtrlRead($IpInput)
$socketS = UDPOpen($sIp, 65533)
If @error <> 0 Then Exit

$sName = GUICtrlRead($LoginInput)
$status = UDPSend($socketS, "login " & $ip & " " & $sName & " " & $port)
GUISetState(@SW_SHOW, $gui)
GUISetState(@SW_HIDE, $lgui)
EndFunc

Func logout()
$status = UDPSend($socketS, "logout " & $id)
Exit
EndFunc

Func SendMsg()
$sData = GUICtrlRead($input)
GUICtrlSetData($input, "")
$status = UDPSend($socketS, $sName & ": " & $sData)
If $status = 0 Then
  MsgBox(0, "ERROR", "Error Server Down :  " & @error)
EndIf
EndFunc

While 1
If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
$data = UDPRecv($socketR, 1024)
If $data <> "" Then
  $rData = StringSplit($data, " ")
  If $rData[1] = "update" Then
   update($data)
  Else
   If $rData[1] = "id" Then
    $id = $rData[2]
   Else
    GUICtrlSetData($chatBox, GUICtrlRead($chatBox) & @CRLF & $data)
   EndIf
  EndIf
EndIf
Sleep(1)
WEnd
Func update($string)
$users = StringSplit($string, " ")
_GUICtrlListView_DeleteAllItems($userList)
For $i = 2 To $users[0]
  _GUICtrlListView_AddItem($userList, $users[$i])
Next
EndFunc
Func Cleanup()
UDPCloseSocket($socketR)
UDPCloseSocket($socketS)
UDPShutdown()
EndFunc
Func quit()
Exit
EndFunc

Hope it helps someone...

Link to comment
Share on other sites

updated: added code explications

Client:

#include <GUIConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiButton.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>

Opt("GUIOnEventMode", 1)
HotKeySet("{esc}", "quit")
Global $socketS, $socketR, $sName, $chatBox, $input, $sendB, $LoginButon, $userList, $id, $var12

UDPStartup()
OnAutoItExitRegister("Cleanup")
$gui = GUICreate("Chat", 600, 500)
$chatBox = GUICtrlCreateEdit("", 10, 10, 490, 440, $ES_READONLY)
$sendB = GUICtrlCreateButton("Send", 10, 460, 50, 20, $BS_DEFPUSHBUTTON)
GUICtrlSetOnEvent($sendB, "SendMsg")
$input = GUICtrlCreateInput("", 70, 460, 370, 20)
$LogOutB = GUICtrlCreateButton("LogOut", 530, 460, 50, 20)
GUICtrlSetOnEvent($LogOutB, "logout")
$userList = _GUICtrlListView_Create($gui, "Users", 510, 10, 80, 440, $LVS_NOCOLUMNHEADER)
_GUICtrlListView_SetColumnWidth($userList, 1, 85)
;Login Gui
$lgui = GUICreate("Login", 100, 200, -1, -1, -1, -1, $gui)
$LoginButon = GUICtrlCreateButton("Login", 10, 75, 80, 20, $BS_DEFPUSHBUTTON)
GUICtrlSetOnEvent($LoginButon, "login")
$LoginInput = GUICtrlCreateInput("", 10, 45, 80, 20)
GUICtrlCreateLabel("Pls Write Your Name To Login", 10, 5, 80, 40)
$IpInput = GUICtrlCreateInput("127.0.0.1", 10, 105, 80, 20)
GUICtrlCreateLabel("Server Ip", 10, 135, 80, 40)
GUISetState(@SW_SHOW, $lgui)
Func login()
;recive
$port = Random(60000, 65532, 1);Random port
$ip = "127.0.0.1"
$socketR = UDPBind($ip, $port);Recive soket
If @error <> 0 Then Exit
;send
$sIp = GUICtrlRead($IpInput);server ip
$socketS = UDPOpen($sIp, 65533);send socket
If @error <> 0 Then Exit

$sName = GUICtrlRead($LoginInput)
UDPSend($socketS, "login " & $ip & " " & $sName & " " & $port); send login comand, IP, Name and PORT
GUISetState(@SW_SHOW, $gui)
GUISetState(@SW_HIDE, $lgui)
EndFunc

Func logout()
$status = UDPSend($socketS, "logout " & $id) ;send logout command and id
Exit
EndFunc

Func SendMsg()
$sData = GUICtrlRead($input)
GUICtrlSetData($input, "")
$status = UDPSend($socketS, $sName & ": " & $sData); Sends name and mssg
If $status = 0 Then
  MsgBox(0, "ERROR", "Error Server Down :  " & @error)
EndIf
EndFunc

While 1
If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
$data = UDPRecv($socketR, 1024) ;wait for data
If $data <> "" Then  ;if data is recived start data analys
  $rData = StringSplit($data, " ")
  If $rData[1] = "update" Then ;if update heather is recived
   update($data) ;update user list
  Else
   If $rData[1] = "id" Then ;if id heather is recived
    $id = $rData[2] ;store ID
   Else
    GUICtrlSetData($chatBox, GUICtrlRead($chatBox) & @CRLF & $data);Write data to chat
   EndIf
  EndIf
EndIf
Sleep(1)
WEnd
Func update($string)
$users = StringSplit($string, " ")
_GUICtrlListView_DeleteAllItems($userList) ;delete old list
For $i = 2 To $users[0]
  _GUICtrlListView_AddItem($userList, $users[$i]);add new list
Next
EndFunc
Func Cleanup(); cleen open sockets
UDPCloseSocket($socketR)
UDPCloseSocket($socketS)
UDPShutdown()
EndFunc
Func quit()
Exit
EndFunc

Server:

#include <GUIConstantsEx.au3>
Opt("GUIOnEventMode", 1)
Global $socket[21], $socketR, $id = ""
Global $user[21][4]
; Set all arrays with nul values
$i = 0
Do
$i = $i + 1
For $j = 1 To 20
  $user[$j][$i] = ""
  $socket[$j] = ""
Next
Until $i = 3

UDPStartup()
OnAutoItExitRegister("Cleanup") ;Function to run if program is closing
$socketR = UDPBind("127.0.0.1", 65533) ;Create listen soket on local host
If @error Then Exit

While 1
$sdata = UDPRecv($socketR, 200) ;Wait to recive data
If $sdata <> "" Then  ;Data recived
  $rData = StringSplit($sdata, " ")
  If $rData[1] = "login" Then ;If data contains a login opp
   For $i = 1 To 20
    If $user[$i][1] = "" Then;Search for empty user slot and seting an  unique id to user
     $id = $i
     ExitLoop
    EndIf
   Next
   $socket[$id] = UDPOpen($rData[2], $rData[4]) ;Open conectoin to the recieved IP and PORT
   ; Store data to user array
   $user[$id][1] = $rData[3];Name
   $user[$id][2] = $rData[2];PORT
   $user[$id][3] = $rData[4];IP
   update($id, 1)
  Else
   If $rData[1] = "logout" Then ;If data contains a logout opp
    $id = $rData[2] ;set user logout id
    update($id, 0) ;update and send active user list
    $user[$id][1] = "" ;clear User data
   Else
    For $i = 1 To 20
     If $user[$i][1] <> "" Then $status = UDPSend($socket[$i], $sdata) ;if no comands are recived loop msg to all users
    Next
   EndIf
  EndIf
EndIf
Sleep(1)
If GUIGetMsg() = $GUI_EVENT_CLOSE Then Exit
WEnd
Func update($var1, $var2)
$userData = "update" ; set comand heather to update
For $i = 1 To 20
  If $var2=0 Then
  If $user[$i][1] <> "" and $var1<>$i Then $userData = String($userData & " " & $user[$i][1]) ;create string of users without the logout user
  Else
  If $user[$i][1] <> "" Then $userData = String($userData & " " & $user[$i][1]); Create user list
  EndIf
Next
For $i = 1 To 20
  If $user[$i][1] <> "" Then
   UDPSend($socket[$i], $userData) ;send user list
   If $var2 = 1 Then UDPSend($socket[$i], $user[$var1][1] & "--- Joined The Chanel") ;send login info
   If $var2 = 0 and $var1<>$i Then UDPSend($socket[$i], $user[$var1][1] & "--- Left The Chanel") ;send logout info
  EndIf
Next
If $var2 = 1 Then UDPSend($socket[$var1], "id " & $var1) ;sent back to the new user his Id
If $var2 = 0 Then UDPCloseSocket($socket[$var1]) ;close socket for logout
EndFunc
Func Cleanup() ;close recive socket befor exit
UDPCloseSocket($socketR)
UDPShutdown()
EndFunc
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...