package Ġcom . la apt u . socket . channel Ċ Ċ import Ġkotlinx . coroutines . experimental . Common Pool Ċ import Ġkotlinx . coroutines . experimental . Job Ċ import Ġkotlinx . coroutines . experimental . android . UI Ċ import Ġkotlinx . coroutines . experimental . launch Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . io .* Ċ import Ġjava . lang . Exception Ċ import Ġjava . net . Inet Address Ċ import Ġjava . net . Socket Ċ Ċ class ĠClient ( private Ġval Ġip Address : ĠString , Ġprivate Ġval Ġserver Port Number : ĠInt ) Ġ: ĠSocket Rule Ġ{ ĊĊĠĠĠ Ġprivate Ġvar Ġclient Socket : ĠSocket ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġoutput Writer : ĠPrintWriter ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġinput Reader : ĠInputStream ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġval Ġread Buffer : ĠByteArray Ġ= ĠByteArray ( 1 0 2 4 ) ĊĠĠĠ Ġprivate Ġvar Ġmessage Listener : ĠMessage Listener ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġval Ġrunning Job Ġ= ĠJob () ĊĠĠĠ Ġprivate Ġvar Ġis Running Ġ= Ġtrue ĊĊĠĠĠ Ġoverride Ġfun Ġstart () Ġ{ ĊĠĠĠĠĠĠĠ Ġlaunch ( Common Pool , Ġparent Ġ= Ġrunning Job ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġserver Address Ġ= ĠInet Address . get ByName ( ipAddress ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient Socket Ġ= ĠSocket ( server Address , Ġserver Port Number ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Writer Ġ= ĠPrintWriter ( Buffered Writer ( OutputStream Writer ( client Socket ?. get OutputStream ())), Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Reader Ġ= Ġclient Socket ?. getInputStream () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . d (" Connected Ġto Ġthe Ġserver Ġat Ġ% s ", Ġip Address ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend Info (" Connected Ġto Ġthe Ġserver Ġat Ġ$ ipAddress ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( isRunning ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinput Reader ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbytes Ġ= Ġit . read ( read Buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinput Message Ġ= ĠString ( read Buffer , Ġ 0 , Ġbytes ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! input Message . isNull OrEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbroad Cast Incoming Message ("( Ġ@ Ġ$ ipAddress Ġ) Ġ$ input Message ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" Error Ġconnecting Ġto Ġthe Ġserver Ġat Ġ% s Ġdue Ġto Ġ: Ġ% s ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġip Address , Ġexception . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbroad Cast Incoming Message ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmessage Listener ?. let Ġ{ Ġmsg Listener Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch ( UI ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmsg Listener . on Message Received ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġis Running Ġ= Ġfalse ĊĠĠĠĠĠĠĠ Ġmessage Listener Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġrunning Job . cancel () ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient Socket ?. close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Writer ?. close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinput Reader ?. close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclient Socket ?. close () ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( exception : ĠException ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠsendMessage ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlaunch ( Common Pool , Ġparent Ġ= Ġrunning Job ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoutput Writer ?. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend Info ( info : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmessage Listener ?. let Ġ{ Ġmsg Listener Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch ( UI ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmsg Listener . on Info Received ( info ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġoverride Ġfun Ġsubscribe To Message ( message Listener : ĠMessage Listener ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . message Listener Ġ= Ġmessage Listener ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠgetType (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠSocket Type . Client ĊĠĠĠ Ġ} Ċ Ċ }