Skip to content

Instantly share code, notes, and snippets.

@Silverbaq
Created January 1, 2018 21:15
Show Gist options
  • Star 45 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save Silverbaq/a14fe6b3ec57703e8cc1a63b59605876 to your computer and use it in GitHub Desktop.
Save Silverbaq/a14fe6b3ec57703e8cc1a63b59605876 to your computer and use it in GitHub Desktop.
A simple socket-server written in Kotlin
package dk.im2b
import java.io.OutputStream
import java.net.ServerSocket
import java.net.Socket
import java.nio.charset.Charset
import java.util.*
import kotlin.concurrent.thread
fun main(args: Array<String>) {
val server = ServerSocket(9999)
println("Server is running on port ${server.localPort}")
while (true) {
val client = server.accept()
println("Client connected: ${client.inetAddress.hostAddress}")
// Run client in it's own thread.
thread { ClientHandler(client).run() }
}
}
class ClientHandler(client: Socket) {
private val client: Socket = client
private val reader: Scanner = Scanner(client.getInputStream())
private val writer: OutputStream = client.getOutputStream()
private val calculator: Calculator = Calculator()
private var running: Boolean = false
fun run() {
running = true
// Welcome message
write("Welcome to the server!\n" +
"To Exit, write: 'EXIT'.\n" +
"To use the calculator, input two numbers separated with a space and an operation in the ending\n" +
"Example: 5 33 multi\n" +
"Available operations: 'add', 'sub', 'div', 'multi'")
while (running) {
try {
val text = reader.nextLine()
if (text == "EXIT"){
shutdown()
continue
}
val values = text.split(' ')
val result = calculator.calculate(values[0].toInt(), values[1].toInt(), values[2])
write(result)
} catch (ex: Exception) {
// TODO: Implement exception handling
shutdown()
} finally {
}
}
}
private fun write(message: String) {
writer.write((message + '\n').toByteArray(Charset.defaultCharset()))
}
private fun shutdown() {
running = false
client.close()
println("${client.inetAddress.hostAddress} closed the connection")
}
}
class Calculator {
fun calculate(a: Int, b: Int, operation: String): String {
when (operation) {
"add" -> return calc(a, b, ::add).toString()
"sub" -> return calc(a, b, ::sub).toString()
"div" -> return calc(a.toDouble(), b.toDouble(), ::div).toString()
"multi" -> return calc(a, b, ::multi).toString()
else -> {
return "Something whent wrong"
}
}
}
// A Calculator (functional programming)
private fun <T> calc(a: T, b: T, operation: (T, T) -> T): T {
return operation(a, b)
}
private fun add(a: Int, b: Int): Int = a + b
private fun sub(a: Int, b: Int): Int = a - b
private fun div(a: Double, b: Double): Double = a / b
private fun multi(a: Int, b: Int): Int = a * b
}
Copy link

ghost commented May 24, 2018

tysir

@Airog
Copy link

Airog commented Aug 15, 2018

HI! Do we really need to create copy of the socket connection?
...
class ClientHandler(client: Socket) {
-> private val client: Socket = client <-
private val reader: Scanner = Scanner(client.getInputStream())
...

@CLOVIS-AI
Copy link

@Airog this is a late reply, but that line doesn't copy anything.

In Kotlin, as in Java, C# and many other languages, variables contain references, not their actual value. Here, the line copies the reference, which is not its content. Copying a reference is virtually free (it's very light); the Socket object here is not modified nor copied.

This could've been written:

class ClientHandler(val client: Socket) {
...

and would've been exactly identical

@phash
Copy link

phash commented Jun 16, 2019

could you please give a client-example as well? Thanks!

@Silverbaq
Copy link
Author

could you please give a client-example as well? Thanks!

Sorry for the late replay (That goes for everyone). I've made a simple Client.kt for you as well.
https://gist.github.com/Silverbaq/1fdaf8aee72b86b8c9e2bd47fd1976f4

@Joozd
Copy link

Joozd commented Feb 14, 2020

First of all: Thanks, this helps me a lot.
Second: If you change Calculator into an object iso a class you don't have to initialize it (there is nothing initialized anyway in it's constructor)

@SmartManoj
Copy link

tysir

meaning?

@remylavergne
Copy link

tysir

meaning?

Thank You Sir ? 🤷‍♂️

@saeedrznr
Copy link

Thanks for this useful codes. its help me a lot and i developed a simple chat app for android devices . I'll be happy if you visit it
https://github.com/saeedrznr/Chat-application-client
https://github.com/saeedrznr/Chat-application-server

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment