Aplikasi ini merupakan pengembangan dari sample aplikasi yg sudah pernah saya bahas pada postingan sebelumnya, aplikasi ini terdiri dari 2 project yaitu :
Aplikasi server memanfaatkan array winsock karena akan menghandle minimal 1 koneksi
Untuk aplikasi klien cukup menggunakan winsock standar (non array).
Sekarang akan kita bahas cara pembuatannya.
Aplikasi server
Aplikasi server menggunakan winsock yg dijadikan array karena akan menerima lebih dari 1 koneksi, untuk menjadikan sebuah winsock menjadi array cukup dengan mengeset properties index = 0
Selain itu agar sebuah winsock bisa menerima koneksi yg masuk, maka winsocknya harus dalam mode “Listen”, untuk keperluan ini kita akan menyiapkan sebuah fungsi misal dengan nama startListening
123456789101112131415161718192021
PrivateFunctionstartListening(ByVallocalPortAsLong)AsBooleanOnErrorGoToerrHandleIflocalPort>0Then'If the socket is already listening, and it's listening on the same port, don't bother restarting it.If(wckServer(0).State<>sckListening)Or(wckServer(0).localPort<>localPort)ThenWithwckServer(0)Call.Close.localPort=localPortCall.ListenEndWithEndIf'Return true, since the server is now listening for clients.startListening=TrueEndIfExitFunctionerrHandle:startListening=FalseEndFunction
Selanjutnya tinggal kita panggil pada event Form_Load
123456789
PrivateSubForm_Load()'1234 adalah port yg digunakan untuk komunikasi'antara server dan klien, nilainya bisa disesuaikanIfstartListening(1234)ThenMsgBox"Status Server ON"ElseMsgBox"Status Server OFF"EndIfEndSub
Selain itu ada beberapa kode yang harus kita lengkapi pada event2x yg dimiliki oleh winsock yaitu event Close, ConnectionRequest, DataArrival dan Error
1234
PrivateSubwckServer_Close(IndexAsInteger)' Close the socket and raise the event to the parent.CallwckServer(Index).CloseEndSub
PrivateSubwckServer_ConnectionRequest(IndexAsInteger,ByValrequestIDAsLong)DimiAsLongDimjAsLongDimblnLoadedAsBooleanOnErrorGoToerrHandle' We shouldn't get ConnectionRequests on any other socket than the listener' (index 0), but check anyway. Also check that we're not going to exceed' the MaxClients property.If(Index=0)Then' Check to see if we've got any sockets that are free.Fori=1TowckServer.UBoundIf(wckServer(i).State=sckClosed)Thenj=iExitForEndIfNexti' If we don't have any free sockets, load another on the array.If(j=0)ThenblnLoaded=TrueCallLoad(wckServer(wckServer.UBound+1))j=wckServer.Count-1EndIf' With the selected socket, reset it and accept the new connection.WithwckServer(j)Call.CloseCall.Accept(requestID)EndWithEndIfExitSub'errHandle:' Close the Winsock that caused the error.CallwckServer(0).CloseEndSub
Event ConnectionRequest berfungsi untuk memfilter koneksi yg masuk, jika ada koneksi yg masuk akan dilakukan pengecekan terlebih dulu apakah ada winsock yg idle (ngangur) jika ada maka koneksi tersebut akan langsung dihandle oleh winsock yg idle tadi, jika tidak maka akan diload terlebih dulu winsock yg baru kemudian langsung menghandle koneksi yg baru masuk tadi.
Teknik ini merupakah salah satu cara untuk melakukan optimasi program jangan sampai aplikasi server meload secara terus menerus objek winsock yg baru untuk setiap koneksi yg masuk.
1234567891011121314151617181920212223
PrivateSubwckServer_DataArrival(IndexAsInteger,ByValbytesTotalAsLong)DimcmdAsStringOnErrorGoToerrHandle' Grab the data from the specified Winsock object, and pass it to the parent.CallwckServer(Index).GetData(cmd)SelectCasecmdCase"get_no_antrian"Callsend(Index,CStr(noAntrian))lblNoAntrian.Caption=noAntriannoAntrian=noAntrian+1' naikkan counter nomor antrianCaseElseCallsend(Index,"perintah tidak dikenal")EndSelectExitSuberrHandle:CallwckServer(Index).CloseEndSub
Event DataArrival berfungsi untuk memproses data yg masuk, untuk kasus aplikasi antrian ini data yang paling valid hanya berupa string “get_no_antrian”, jika datanya valid akan langsung dikirimkan nomor antrian terakhir ke klien yg mengirimkan string “get_no_antrian” dg memanggil prosedur send.
Untuk aplikasi server sy rasa sudah cukup akan kita lanjutkan dg aplikasi klien.
Aplikasi Klien
Untuk aplikasi klien lebih sederhana lagi, yg kita butuhkan cukup sebuah fungsi untuk melakukan koneksi ke server
1
PrivateConstconTungguAsLong=100000
1234567891011121314151617181920212223
PrivateFunctionisConnected(ByValipServerAsString,ByValportAsLong)AsBooleanStaticiAsLongOnErrorResumeNextIfmyClient.State<>sckClosedThenmyClient.Close' close existing connectionmyClient.RemoteHost=ipServermyClient.RemotePort=portmyClient.ConnectWithmyClientDoUntil.State=sckConnectedDoEventsi=i+1Ifi>=conTungguTheni=0ExitFunctionEndIfLoopEndWithisConnected=myClient.State=sckConnectedEndFunction
Contoh pemanggilan fungsi diatas seperti berikut :
123456789101112
PrivateSubcmdAmbilNoAntrian_Click()DimipServerAsStringDimcmdAsStringipServer="127.0.0.1"cmd="get_no_antrian"' 1234 ada port yg menyesuaikan port yg ada di serverIfisConnected(ipServer,1234)ThenmyClient.SendDatacmdEndIfEndSub
Untuk mengetahui data yang dikirim balik oleh server kita bisa memanfaatkan event DataArrival yg dimiliki oleh objek winsock
Aplikasi diatas belum menggunakan database sama sekali, sehingga jika aplikasi server ditutup maka counter nomor antrian akan dimulai dari 1 lagi, dan sy berharap tidak ada pertanyaan bagaimana menyimpan counter nomor antriannya ke database atw bagaimana cara menampilkan nomor atrian terakhir klo servernya error :D.