Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
153
Task/Chat-server/Kotlin/chat-server.kotlin
Normal file
153
Task/Chat-server/Kotlin/chat-server.kotlin
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.io.OutputStreamWriter
|
||||
import java.io.Writer
|
||||
import java.net.ServerSocket
|
||||
import java.net.Socket
|
||||
import java.util.ArrayList
|
||||
import java.util.Collections
|
||||
|
||||
class ChatServer private constructor(private val port: Int) : Runnable {
|
||||
private val clients = ArrayList<Client>()
|
||||
|
||||
private val onlineListCSV: String
|
||||
@Synchronized get() {
|
||||
val sb = StringBuilder()
|
||||
sb.append(clients.size).append(" user(s) online: ")
|
||||
for (i in clients.indices) {
|
||||
sb.append(if (i > 0) ", " else "").append(clients[i].clientName)
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
try {
|
||||
val ss = ServerSocket(port)
|
||||
while (true) {
|
||||
val s = ss.accept()
|
||||
Thread(Client(s)).start()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun registerClient(client: Client): Boolean {
|
||||
for (otherClient in clients) {
|
||||
if (otherClient.clientName!!.equals(client.clientName!!, ignoreCase = true)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
clients.add(client)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun deRegisterClient(client: Client) {
|
||||
var wasRegistered = false
|
||||
synchronized(this) {
|
||||
wasRegistered = clients.remove(client)
|
||||
}
|
||||
if (wasRegistered) {
|
||||
broadcast(client, "--- " + client.clientName + " left ---")
|
||||
}
|
||||
}
|
||||
|
||||
private fun broadcast(fromClient: Client, msg: String) {
|
||||
// Copy client list (don't want to hold lock while doing IO)
|
||||
var clients: List<Client> = Collections.emptyList()
|
||||
synchronized(this) {
|
||||
clients = ArrayList(this.clients)
|
||||
}
|
||||
for (client in clients) {
|
||||
if (client.equals(fromClient)) {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
client.write(msg + "\r\n")
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inner class Client internal constructor(private var socket: Socket?) : Runnable {
|
||||
private var output: Writer? = null
|
||||
var clientName: String? = null
|
||||
|
||||
override fun run() {
|
||||
try {
|
||||
socket!!.sendBufferSize = 16384
|
||||
socket!!.tcpNoDelay = true
|
||||
val input = BufferedReader(InputStreamReader(socket!!.getInputStream()))
|
||||
output = OutputStreamWriter(socket!!.getOutputStream())
|
||||
write("Please enter your name: ")
|
||||
var line: String
|
||||
while (true) {
|
||||
line = input.readLine()
|
||||
if (null == line) {
|
||||
break
|
||||
}
|
||||
if (clientName == null) {
|
||||
line = line.trim { it <= ' ' }
|
||||
if (line.isEmpty()) {
|
||||
write("A name is required. Please enter your name: ")
|
||||
continue
|
||||
}
|
||||
clientName = line
|
||||
if (!registerClient(this)) {
|
||||
clientName = null
|
||||
write("Name already registered. Please enter your name: ")
|
||||
continue
|
||||
}
|
||||
write(onlineListCSV + "\r\n")
|
||||
broadcast(this, "+++ $clientName arrived +++")
|
||||
continue
|
||||
}
|
||||
if (line.equals("/quit", ignoreCase = true)) {
|
||||
return
|
||||
}
|
||||
broadcast(this, "$clientName> $line")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
deRegisterClient(this)
|
||||
output = null
|
||||
try {
|
||||
socket!!.close()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
socket = null
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
internal fun write(msg: String) {
|
||||
output!!.write(msg)
|
||||
output!!.flush()
|
||||
}
|
||||
|
||||
internal fun equals(client: Client?): Boolean {
|
||||
return (client != null
|
||||
&& clientName != null
|
||||
&& client.clientName != null
|
||||
&& clientName == client.clientName)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
var port = 4004
|
||||
if (args.isNotEmpty()) {
|
||||
port = Integer.parseInt(args[0])
|
||||
}
|
||||
ChatServer(port).run()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue