corl455 Posted April 8, 2011 Share Posted April 8, 2011 (edited) Alright, so I thought I'd learn a little bit more about network communications in programing, so I wrote two programs (server & client), where the server executes a command sent by the client. So with the help of some of the examples I got the program to work, but, after the client disconnects (just closes the program), if the client trys to reconnect, you can, but none of the commands works. How would I fix this? Also, are there way's of optimizing this to use less CPU. From what I can tell it's not using much, but I haven't throughly tested it yet. here is my server code: expandcollapse popupOpt('MustDeclareVars', 1) Opt('TrayIconHide', 1) Main() Func Main() local $file = FileOpen("sev.txt", 0) If $file = -1 Then filewrite( "sev.txt", inputbox( "Server", "Please input the name of the server pc")) Exit EndIf local $char = FileRead($file) FileClose($file) local $IP = TCPNameToIP($char) Local $szIPADDRESS = $IP Local $nPORT = 33891 Local $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted Local $msg, $recv TCPStartup() $MainSocket = TCPListen($szIPADDRESS, $nPORT) If $MainSocket = -1 Then Exit $ConnectedSocket = -1 Do $ConnectedSocket = TCPAccept($MainSocket) Until $ConnectedSocket <> -1 $szIP_Accepted = SocketToIP($ConnectedSocket) While 1 $recv = TCPRecv($ConnectedSocket, 2048) execute($recv) WEnd TCPShutdown() EndFunc Func SocketToIP($SHOCKET) Local $sockaddr, $aRet $sockaddr = DllStructCreate("short;ushort;uint;char[8]") $aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _ "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr)) If Not @error And $aRet[0] = 0 Then $aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3)) If Not @error Then $aRet = $aRet[0] Else $aRet = 0 EndIf $sockaddr = 0 Return $aRet EndFunc And here is my Client: #include <GUIConstantsEx.au3> Opt('MustDeclareVars', 1) Main() TCPShutdown() Func Main() Local $ConnectedSocket, $szData, $szIPADDRESS Local $nPORT = 33891 TCPStartup() local $ip = msgbox( 4, "Client", "Do you want to use NameToIP?") if $ip = 6 Then local $g = InputBox(" ", "Please input PC name") $szIPADDRESS = TCPNameToIP($g) else $szIPADDRESS = InputBox( "Input IP", "Please input the IP of the server", "127.0.0.1") EndIf $ConnectedSocket = -1 $ConnectedSocket = TCPConnect($szIPADDRESS, $nPORT) If @error Then MsgBox(4112, "Error", "TCPConnect failed with WSA error: " & @error) Else While 1 $szData = InputBox("Data for Server", @LF & @LF & "Enter data to transmit to the SERVER:") if @error Or $szData = "" Then ExitLoop TCPSend($ConnectedSocket, $szData) If @error Then ExitLoop WEnd EndIf EndFunc Any improvements or suggestions are welcome. I wrote this pretty quickly. EDIT: yes, there are a few remains from the example programs, and unnecessary variable declarations, I haven't completely cleaned it up. Edited April 8, 2011 by corl455 Link to comment Share on other sites More sharing options...
bwochinski Posted April 9, 2011 Share Posted April 9, 2011 (edited) The main problem - only being able to connect the first time - is due to your server script being forever stuck in the TCPRecv() loop after someone connects. Even if they disconnect, there's nothing to kick the server back out of there. A quick fix might be something like this: TCPStartup() $MainSocket = TCPListen($IP, $nPORT) If $MainSocket = -1 Then Exit While 1 $ConnectedSocket = -1 Do $ConnectedSocket = TCPAccept($MainSocket) Sleep(50) Until $ConnectedSocket <> -1 While 1 $recv = TCPRecv($ConnectedSocket, 2048) If @error <> 0 Then ExitLoop If StringLen($recv) Then execute($recv) EndIf Sleep(50) WEnd WEnd In this way, when the TCPRecv function throws an @error code, that loop will be exited, and the larger loop will go back to the "DO - UNTIL" loop that accepts connections. I also threw some Sleep() calls in there to slow down the loops a bit and ease CPU usage. Edited April 9, 2011 by bwochinski Link to comment Share on other sites More sharing options...
corl455 Posted April 10, 2011 Author Share Posted April 10, 2011 Alright, thank you. I don't have time to try it out now, but I will as soon as possible. Link to comment Share on other sites More sharing options...
4Eyes Posted April 12, 2011 Share Posted April 12, 2011 corl455, In your server script, if you move the TCPStartup() up to be the 1st statement under Func Main() then it actually works, otherwise the TCPNameToIP() doesn't work and it fails. If you change the Execute() to Run() then you can send 'Notepad.exe' to the server and it will run Notepad. That's pretty cool. 4Eyes Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now