Jump to content

Need Help if possible


sgufa
 Share

Recommended Posts

Hi All.

I've made a little client/server program for my company. This program works flawlessly if 1 computer acts as client and 1 other acts as server. The server app sends/receive strings to/from client. The client app connects to the server app and this one displays a message when client connects. Now. My problem is this: I'd want to allow multiple connections to server app in the same time. How to make it possible? with "standard" listening the server responds only to the first client that create socket, other clients can't make socket connection because server can't "ear" anymore on that specific port. Is there a way to create a listening process on one port and then (on client's connection requests) server can manage multiple connections on that port (eg. creating child sockets binding the same port, leaving the listening process "free to ear" other requests)?

Link to comment
Share on other sites

Ok, not sure if you are doing this in autoit or what, some more details would help...

I've done something similar to this in Java, where I had a daemon listener on the one port that is opened up for connections. whenever a client connects to the server, instead of connecting on that port the daemon hands them a different socket connection, so it can continue listening on the original port.

This way multiple clients can send the connect request to the same port, and get handed different connections. I dont know if that exactly answers your questions, but hopefully it helps some :-)

Link to comment
Share on other sites

Ok, not sure if you are doing this in autoit or what, some more details would help...

I've done something similar to this in Java, where I had a daemon listener on the one port that is opened up for connections. whenever a client connects to the server, instead of connecting on that port the daemon hands them a different socket connection, so it can continue listening on the original port.

This way multiple clients can send the connect request to the same port, and get handed different connections. I dont know if that exactly answers your questions, but hopefully it helps some :-)

exactly what i'm trying to to without results... please help! :)

Link to comment
Share on other sites

ok. I solved part of my problems (server side) also thanks this post

TCP Problem

My code is very similar to this regarding tcp connections handling.

I can't find a way to send a specific message to a specific client.

Ok. Take for example that code.

I must specify the socket name ("$ConnectedSocket[$track]") in order to send "that" message to "that" client.

In my case the client sends his name to server. Is it possible to map name to "$ConnectedSocket[$track]" ( even using a multiple array[j]) and then use the name for sending messages?

Please help me. I'm in real trouble!

Link to comment
Share on other sites

I'm trying to solve the problem myself but i still can't send a message only to a client. The server app is able to send message only to the last client connected. If anyone has a idea for how to solve this problem, please post here. Many thanks

Link to comment
Share on other sites

OK. The server side is still in test phase. When all will work i'll do code optimization. For now i'm using some reference code. As written in previous posts, i'm trying to use Muscle's script posted in this Thread TCP Problems in order to test if it can solve part of my problems.

What I still can't do you will find between ";??????????????????????????????" rows.

Many thanks

Server test system;

#include <GUIConstants.au3>

; TCP-Prefences
; =================
Global $ip = "192.168.1.2"
Global $port = 5500
Global $MaxConc = 100                               ; max clients
Global Const $MaxLength = 2048                      ; max data-length

Global $MainSocket = TCPStartServer($port, $MaxConc)
If @error <> 0 Then
    MsgBox(16, "TCP-Mistake", "Program closes!")
    Exit
EndIf
Global $ConnectedSocket[$MaxConc]
Global $CurrentSocket = 0
Local $track = 0
Global Const $MaxConnection = ($MaxConc - 1)

; TCP-Functions
; ==============
For $track = 0 To $MaxConnection Step 1
    $ConnectedSocket[$track] = -1
Next

Dim $GOOEY = GUICreate("My Server (IP: " & $ip & ")",300,240)
Dim $edit = GUICtrlCreateEdit("",10,10,280,180)
$Button_1 = GuiCtrlCreateButton("send", 130, 210, 60, 25)
GUISetState()

While 1
    $msg = GUIGetMsg()
    $ConnectedSocket[$CurrentSocket] = TCPAccept($MainSocket)
    If $ConnectedSocket[$CurrentSocket] <> -1 Then
        $CurrentSocket = SocketSearch()
    EndIf
    $track = 0
    For $track = 0 To $MaxConnection Step 1
        ; => get
        If $ConnectedSocket[$track] <> -1 Then
            $data = TCPRecv($ConnectedSocket[$track], $MaxLength)
            If $data <> "" And $data <> "-CLOSE-" Then
                ; Data - ListView
                If StringLeft($data, 6) = "-DATA-" Then
                    Dim $client_data = StringTrimLeft($data, 6)
                    
                    
                    GUICtrlSetData($edit, _
            $ConnectedSocket[$track] & " > " & $data & @CRLF & GUICtrlRead($edit))
                EndIf
            ElseIf @error Or $data = "-CLOSE-" Then
                TCPCloseSocket($ConnectedSocket[$track])
                $ConnectedSocket[$track] = -1
                $CurrentSocket = SocketSearch()
            EndIf
        EndIf
    Next
    If $msg = $GUI_EVENT_CLOSE Then 
        ExitLoop
    EndIf
    If $msg = $Button_1 Then 
        ;????????????????????????????????????????
        ;how to make a function that select that particular client with that specific "$ConnectedSocket[$track]" and send message to it?
        ;????????????????????????????????????????
    EndIf
WEnd

Func SocketSearch()
    Local $track = 0
    For $track = 0 To $MaxConnection Step 1
        If $ConnectedSocket[$track] = -1 Then
            Return $track
        Else
        EndIf
    Next
EndFunc

Func TCPStartServer($port, $MaxConnect = 1)
    Local $socket
    $socket = TCPStartup()
    Select
        Case $socket = 0
            SetError(@error)
            Return -1
    EndSelect
    $socket = TCPListen($ip, $port, $MaxConnect)
    Select
        Case $socket = -1
            SetError(@error)
            Return 0
    EndSelect
    SetError(0)
    Return $socket
EndFunc


Func _ArrayDisp(Const ByRef $avArray, $sTitle)
    Local $iCounter = 0, $sMsg = ""

    If (Not IsArray($avArray)) Then
        SetError(1)
        Msgbox(4096, "Note", $avArray & " non è un array")
        Return 0
    EndIf

    For $iCounter = 0 To UBound($avArray) - 1
        $sMsg = $sMsg & "[" & $iCounter & "]    = " & StringStripCR($avArray[$iCounter]) & @CR
    Next

    MsgBox(4096, $sTitle, $sMsg)
    SetError(0)
    Return 1
EndFunc   



Func OnAutoItExit()
    ; close TCP-Socket, TCP-Service
    Local $MainSocket
    TCPCloseSocket($MainSocket)
    TCPShutdown()
EndFunc ;
Link to comment
Share on other sites

so...

this script creates another socket connection ($ConnectedSocket[$track]) when a client connects to server.When the client connects to server, it sends a message with its name. What I need is to create another array containing the number of socket and the name of client(eg. array[$ConnectedSocket[$track]][clientname]). This array must be updated every time the server creates new connection. The rest of the scripting doesn't matter. I can do it by myself. Please help me

Link to comment
Share on other sites

OK, I don't have time to go over all of your code, but you yourself answered your own question. what you need is something like this

Global $ConnectList[$MaxConc+1][2]
$ConnectList[0][0]=1
oÝ÷ ÚÚ¢{Z{azX¬¶êº'§¶v¦zÊ®¢Ö§vÊëlN§¢wjw°rX×(w¶ÆvØ^wè®f­í¢Ø^jºÚÉ«­¢+ØÀÌØí
½¹¹Ñ1¥ÍÑlÀÌØí
½¹¹Ñ1¥ÍÑlÁulÁuulÁtôÀÌØí9Ý
±¥¹Ñ9µ(ÀÌØí
½¹¹Ñ1¥ÍÑlÀÌØí
½¹¹Ñ1¥ÍÑlÁulÁuulÅtôÀÌØí9ÝM½­ÐoÝ÷ ئºÈ§Mú
çyËKËtÑ«­çÞ­éÜzÚ-çâ®Ë@½¨¥i¹^½ç-¢º¶®¶²N«yú+Ó~¢yÞrÒâ²Ý4².ÖÞw+zg§µç^½êò¶)jw°rX×(w¶Æ®¶­sbb33c´6öææV7DÆ7E³Õ³Ò³ÒoÝ÷ Ø l¢f¤zË«zØZ¶ØZµÚ²z-{yÛazö¥¹êÓ~k¨Ëhjú"u©Þ®º+60éÚrX×b±Ê'ç-³*.Â)eÁ©í¶Þ²íÓ~¢yÞrÒâ²Ö§u«,   Úì/j[7è*'ç-.+-ÓB7öi^jø§Øb²«¶êm£*.N«z+&¢·­©èìÊ좻b§jºÚÉ©ÝjÇ­Èmº.ayú+ºj+éi~)^².Ü¢zWmêÞ²ém³*.çNâÖ©j»bréZ®ÊëgºfÞ­¼§jg²¢ì"[¬y§îËb¢ybëaÍ7èÔ^~+-éÚê¶'§µ«­¢+ÙÕ¹}¥¹
±¥¹ÑM½­Ð ÀÌØí9I¤)½ÈÀÌØí
M
½Õ¹ÐôÄѼÀÌØí
½¹¹Ñ1¥ÍÑlÁulÁt)¥ÀÌØí
½¹¹Ñ1¥ÍÑlÀÌØí
M
½Õ¹ÑulÁtôÀÌØí9IÑ¡¸ÉÑÕɸÀÌØí
½¹¹Ñ1¥ÍÑlÀÌØí
M
½Õ¹ÑulÅt)¹áÐ)ÉÑÕɸ´Ä)¹Õ¹

This will return the socket number of the client with the name passed to the function, or -1 if not found. I hope this helps

Edit: Be aware that I have not tested any of this, and there may be syntax errors as I wrote it in the browser window

Edited by improbability_paradox
Link to comment
Share on other sites

@improbability_paradox

MANY THANXXXXX

Solved!

Now another question: if client loses connection how to check it from server and then delete it from the array?

OK, I've revised the function _FindClientSocket so that it will be a little bit more useful, and so that it will help in updating the array. The new function is

Func _FindClientSocket($CRef, $CFOpt=0)
if not($CFOpt=1) then $CFOpt=0
for $CSCount = 1 to $ConnectList[0][0]
if $ConnectList[$CSCount][$CFOpt]=$CRef then 
SetExtended($CSCount)
return $ConnectList[$CSCount][($CFOpt*-1)+1]
endif
next
return -1
endfunc

OK, now the revised function can search by Client name, or by Socket. By default it will search by client name and will return the socket if found (a -1 if not). If you pass the optional second parameter as a 1 (example: $x=_FindClientSocket($SocketNumber,1)) then it will search by socket number and return the Client Name. In both cases, the macro @Extended will be set with the Vector where the information is found in $ConnectList. You can use this macro to determine what entries need to be removed from the array when a client disconnects.

I recall a function which I wrote a while ago, for a script of my own, that can probably be adapted to resort/adjust the array $ConnectList. I will dig it up and post it soon

Link to comment
Share on other sites

Here is the code from the other function I mentioned. It has been altered so as to work outside of my original script, but as such I have not tested it since editting it for this post. If it doesn't work as expected, I will post another revision when I have time.

Func _AlterArray(ByRef $aArray, $APos1, $Apos2=-1)
    Switch $Apos2
        Case -1
            for $AACount=$APos1 to UBound($aArray, 1)-2
                for $AACount2=0 to UBound($aArray, 2)-1
                    $aArray[$AACount][$AACount2]=$aArray[$AACount+1][$AACount2]
                Next
            Next
            for $AACount2=0 to UBound($aArray, 2)-1
                $aArray[$AACount][$AACount2]=""
            Next
        Case Else
            for $AACount=0 to UBound($aArray, 2)-1
                Local $aASwitch=$aArray[$APos1][$AACount]
                $aArray[$APos1][$AACount]=$aArray[$Apos2][$AACount]
                $aArray[$Apos2][$AACount]=$aASwitch
            Next
    EndSwitch
    
    Return
EndFuncoÝ÷ Øp¢é]mçW)¶¬jëh×6$x=_FindClientSocket("ClientName")
if not $x=-1 then 
$ConnectList[0][1]=@extended
_AlterArray($ConnectList, $ConnectList[0][1])
$ConnectList[0][0] -= 1
endif

Where "ClientName" is the name of the client you want to delete from the array. The other entries will be moved up one position.

Also note that this function has the ability to swap the entries from two separate vectors in the array. (If for some reason you want/need to do that). There were other features but they didn't seem to apply to your script, so I removed them from the function so as to keep it as un-complicated as possible.

Edit: as far as detecting when a client disconnects, I'm afraid that I cant really help you.

Edited by improbability_paradox
Link to comment
Share on other sites

@improbability_paradox

your functions do the work! Great!

i've adapted them a little to apply to my script.

@improbability_paradox & @All

Now i have this situation:

client connects to server sending "clientname" and "group"

server stores info in 1 array with these dimension:

$cltinfo[100][3]

infos are stored this way:

$cltinfo[$track][0] = "socketname"

$cltinfo[$track][1] = "clientname"

$cltinfo[$track][2] = "client group"

Now I have socket number, client ad group mapped very well!

Now I've another problem

Is it possible to "link" the array to a treeview like this?

Treeview

|_Client Group1

|      |_clientname1

|      |_clientname2

|      .

|      .

|_Client Group2

          |_clientnamex

          |_clientnamey

In this way i'd want to group all clients with the same "client group" into a single "client-group" node

Edited by sgufa
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...