Hur får man bra flyt på socket programmering - Blocking read ?

Permalänk

Hur får man bra flyt på socket programmering - Blocking read ?

Detta är inte en fråga hur man programmerar med grundlig socket eller vad socket är. Denna fråga handlar om praktisk teknik angående socket när man använder blocking read.

Jag använder ett språk som heter Java och jag har en socketserver och en socketklient. Dessa två ska både tala med varandra och skriva med varandra. Problemet är att jag får inte det att fungera för dem båda låser sig.

Jag använder något som heter blocking read, vilket betyder att den(klient/server) väntar på svar från sin anslutne. När den har fått svar från sin anslutne, så fortsätter programmet som vanligt. Alltså programmet stannar till och lyssnar med andra ord.

Jag har en programmeringssekvens som ser ut så här:

Server & Klient -------------------------------- Start ------------------- Lyssna Start Acceptera Acceptera ------------ Skicka ------------ ----------------- ------------ ----------------- Läs ----------------- ------------ Läs

Problemet är att när min klient skickar data till server så uppfattar inte server något. När server går i läsfunktion så finns det inget att läsa, utan server fortsätter då att lyssna på klienten. När klient går i läsfunktion så händer det absolut inget. Nu står både server och klient i läsfunktion och lyssnar.

Mitt problem är att få till en bra struktur så att när klient skickar så ska server uppfatta detta när den går i läsfunktion.

Samtidigt så är blocking read väldigt bra för att den väntar ju på hela meddelandet ska skickas, istället för om jag skickar ett långt meddelande och servern läser bara halva meddelandet. Då är det ju en misslyckad kommunikation.

Så har ni några praktiska förslag på hur man löser dessa problem?

Javaklasserna som jag använde är följande för klient är:

socket = new Socket(ip, port); inputStream = socket.getInputStream(); bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); outputStream = this.socket.getOutputStream(); bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));

För server är det:

inputStream = socket.getInputStream(); bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); outputStream = socket.getOutputStream(); bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));

Permalänk
Medlem

Lägg din Blocking read i en egen tråd.
Nu kan du ha en timeout på den tråden.
Skicka om meddelandet om du inte får svar inom viss tid.

Permalänk
Medlem
Skrivet av heretic16:

Samtidigt så är blocking read väldigt bra för att den väntar ju på hela meddelandet ska skickas, istället för om jag skickar ett långt meddelande och servern läser bara halva meddelandet. Då är det ju en misslyckad kommunikation.

Du arbetar utifrån ett felaktigt antagande. Blocking eller non-blocking säkerställer inte på något vis att kompletta "meddelanden" (fnuttar för att det inte existerar något meddelande när du väl skickat det, utan bara en byteström) tas emot. Om du skickar något tillräckligt långt kommer inte hela "meddelandet" med när du läser från socketen oavsett blocking. För att hantera detta definierar du ett protokoll och paketerar datan med så du kan skilja på olika meddelanden och läsa till en buffer tills du har ett komplett meddelande.

Skrivet av mwi:

Skicka om meddelandet om du inte får svar inom viss tid.

Det är TCP:s problem att se till att data kommer fram. Använder man TCP skickas redan data om om den inte kommer fram.

Visa signatur

Spela Swemantle! Du vet att du vill.

Ibland har jag fel, men då är det någon annans fel.

Permalänk
Skrivet av mwi:

Lägg din Blocking read i en egen tråd.
Nu kan du ha en timeout på den tråden.
Skicka om meddelandet om du inte får svar inom viss tid.

Okej. Det är så att jag skapar faktiskt egen tråd efter accept. Då kan jag använda flera klienter. Jag har skrivit en enkel Java-kod.

Här är en klass vars uppgift är att lyssna av nya klienter som vill ansluta. Denna klass driver en tråd.

public class Main { private static Scanner scanner; private static ListenConnections listenThread; public static void main(String[] args) throws NumberFormatException, IOException { /* * Enter a port of this server */ scanner = new Scanner(System.in); System.out.print("Enter a port number above 1024 for this server: "); String port = scanner.nextLine(); /* * Run the threads now. New accept means new thread */ listenThread = new ListenConnections(Integer.parseInt(port)); listenThread.start(); } }

Tråden är den som ser till så det blir ett accept mellan klient och server

public class ListenConnections extends Thread { /* * Fields */ private ServerSocket serverSocket; private Socket socket; private Storage storage; private Connection connection; /* * Constructor */ public ListenConnections(int port) throws IOException { /* * Create the server socket and a storage class */ serverSocket = new ServerSocket(port); storage = new Storage(); } /* * This will listen after new connections(non-Javadoc) * @see java.lang.Thread#run() */ @Override public void run() { while(true) { /* * Wait until we get a connection with a client. * Then we include the socket and also a storage class */ try { socket = serverSocket.accept(); System.out.println("New connection from " + socket.getInetAddress().getHostAddress() + ":" + socket.getPort()); connection = new Connection(socket, storage); connection.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }

När vi får ett accept, så bildas det en nytt objekt vid namn connection som du ser ovan. Denna klass är också en tråd.

Här är klassen Connection.

public class Connection extends Thread { /* * Private fields */ private Socket socket; private Storage storage; private InputStream inputStream; private BufferedReader bufferedReader; private OutputStream outputStream; private BufferedWriter bufferedWriter; private String clientIp; private int clientPort; private boolean connected; public Connection(Socket socket, Storage storage) throws IOException { this.socket = socket; this.storage = storage; /* * Save the ID of the client */ clientIp = this.socket.getInetAddress().getHostAddress(); clientPort = this.socket.getPort(); /* * Input and output streams */ inputStream = this.socket.getInputStream(); bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); outputStream = this.socket.getOutputStream(); bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); /* * Connected */ connected = true; } @Override public void run() { /* * As long we have connection with our client, run this while loop */ try { /* * Loop as long we have connection */ while (connected) { /* * Read the command */ System.out.println("Read..."); String command = bufferedReader.readLine(); // Blocking System.out.println("Result: " + command); /* * Split the command with "#" */ String[] commands; try { commands = command.split("#"); }catch(NullPointerException e) { /* * If we get a null pointer exception here, that means we have lost connection with our client */ disconnect(); return; // End the run() - End this loop } /* * What should we do - GET or SET? */ String send = null; switch (commands[0]) { case "GET_OCTAVE": /* * Get the values from the storage class to GNU OCtave */ send = storage.getSampleTime() + "#" + storage.getPwmStartSignal() + "#" + storage.getReferencePoint() + "#" + storage.getHorizon() + "#" + storage.getSensorSlope() + "#" + storage.getSensorOffset() + "#" + storage.getRunning(); /* * Send now to our client */ System.out.println(send); bufferedWriter.write(send.length()); // We first send length bufferedWriter.write(send); break; case "SET_OCTAVE": /* * Set the values from the storage class from GNU Octave */ storage.setInputSignal(commands[1]); storage.setOutputSignal(commands[2]); storage.setTime(commands[3]); System.out.println("From Octave - Time : " + commands[3]); break; case "GET_ANDROID": /* * Get the values from the storage class to Android app */ send = storage.getInputSignal() + "#" + storage.getOutputSignal() + "#" + storage.getTime(); /* * Send now to our client */ System.out.println(send); bufferedWriter.write(send); break; case "SET_ANDROID": /* * Set the values to the storage class from Android app */ storage.setSampleTime(commands[1]); storage.setPwmStartSignal(commands[2]); storage.setReferencePoint(commands[3]); storage.setHorizon(commands[4]); storage.setSensorSlope(commands[5]); storage.setSensorOffset(commands[6]); storage.setRunning(commands[7]); System.out.println("From android - Sample Time: "+ commands[1]); break; default: break; } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * Connection closed */ private void disconnect() { System.out.println("Disconnection from " + clientIp + ":" + clientPort); try { socket.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } connected = false; } }

Så du menar att jag ska ha en ytterligare tråd inuti klassen Connection som hela tiden läser, men inte skickar?

Permalänk
Skrivet av LemonIllusion:

Du arbetar utifrån ett felaktigt antagande. Blocking eller non-blocking säkerställer inte på något vis att kompletta "meddelanden" (fnuttar för att det inte existerar något meddelande när du väl skickat det, utan bara en byteström) tas emot. Om du skickar något tillräckligt långt kommer inte hela "meddelandet" med när du läser från socketen oavsett blocking. För att hantera detta definierar du ett protokoll och paketerar datan med så du kan skilja på olika meddelanden och läsa till en buffer tills du har ett komplett meddelande.

Det är TCP:s problem att se till att data kommer fram. Använder man TCP skickas redan data om om den inte kommer fram.

Så du menar att ett protokoll kan vara att skicka en sträng där varje meddelande separeras med "#"? Eller det kanske är för billigt gjort?

Permalänk
Medlem
Skrivet av heretic16:

Så du menar att ett protokoll kan vara att skicka en sträng där varje meddelande separeras med "#"? Eller det kanske är för billigt gjort?

Ja, då har du definierat ett protokoll. Så länge # inte kan förekomma i själva meddelandet kommer det duga fint.

Visa signatur

Spela Swemantle! Du vet att du vill.

Ibland har jag fel, men då är det någon annans fel.

Permalänk
Medlem
Skrivet av heretic16:

Så du menar att jag ska ha en ytterligare tråd inuti klassen Connection som hela tiden läser, men inte skickar?

Nej, eftersom du redan har din connection så behövs det inte. Jag menar att du sätter en timeout någonstans så att om du hamnar i ett läge där du inte får svar inom en viss tid så vet du att nåt har gått fel och du kan då starta om din connection. Du behöver göra detta på både klienten och servern.

Det finns flera olika sätt att ska skapa en timeout och vilket som är bäst kan jag inte säga på rak arm. Var ett tag sen jag programmerade med sockets.

Men när jag kodar multitrådat med trådar som kan hänga sig så brukar jag skapa en timeout tråd som kan nollställas ifrån den tråden som kan hänga sig.

Permalänk
Medlem
Skrivet av LemonIllusion:

Det är TCP:s problem att se till att data kommer fram. Använder man TCP skickas redan data om om den inte kommer fram.

Sant, men nu jag antar jag att det kraschar högre upp i kedjan.

Permalänk
Skrivet av mwi:

Nej, eftersom du redan har din connection så behövs det inte. Jag menar att du sätter en timeout någonstans så att om du hamnar i ett läge där du inte får svar inom en viss tid så vet du att nåt har gått fel och du kan då starta om din connection. Du behöver göra detta på både klienten och servern.

Det finns flera olika sätt att ska skapa en timeout och vilket som är bäst kan jag inte säga på rak arm. Var ett tag sen jag programmerade med sockets.

Men när jag kodar multitrådat med trådar som kan hänga sig så brukar jag skapa en timeout tråd som kan nollställas ifrån den tråden som kan hänga sig.

Så om jag inte får svar inom 20 ms så ska jag hoppa vidare eller totalt börja om?

Okej, men då vet jag att det är timeouts jag måste implementera Jag testar implementera på klienterna först.

Permalänk
Medlem

@heretic16: Kanske ska vänta lite mer än 20ms, speciellt om du kommunicerar över internet.
Jag hade stängt ner min connection snyggt och sen börjat om.

Men kolla LemonIllusion's förslag om ett protokoll.

Permalänk
Skrivet av mwi:

@heretic16: Kanske ska vänta lite mer än 20ms, speciellt om du kommunicerar över internet.
Jag hade stängt ner min connection snyggt och sen börjat om.

Men kolla LemonIllusion's förslag om ett protokoll.

Hmm. Jag testade att ha timeout på klienten, men resultatet blev det samma. Så fort jag får ett accept igen så skickar klient -> server och sedan så börjar server att lyssna efter data. Vilket upprepar processen igen...

Jag hade definierat ett protokoll redan Jag förväntade mig att ett protokoll ska följa en viss krånglig standard. Men strängar och avgränsare går tydligen bra.

Edit:
Man skulle ha haft så att om klienten inte får något inom X sekunder så kör den bara vidare.

Permalänk

Jag tror jag gör så här:

Server har blockerad läsning. Dvs den inväntar svar.

Klient läser hur mycket data som finns. Klient börjar först att läsa storleken på datan t.ex 0..255 och sedan skapar den en bytes array med 0..255 element och läser resterande av datan. Finns det inge data, dvs inläsningen blir 0. Ja då skiter klienten att läsa data.

Vad tror ni om detta?

Permalänk

Hjälp, använd inte skräpjava för sånt här

Ett enkelt råd, ska du skriva små enkla eller mer komplexa program där socketprogrammering ingår använd inte Java. Det är alldeles för skräpigt. Använd Rust istället, det är ett mycket mer low level språk men, det har ett så mycket enklare gränssnitt samt pakethanterare för att använda tredjepartsbibliotek än Java. Något som tar 100 rader kod i Java att skriva, när det gäller detta ämnet kan du skriva med ca 10 rader om inte mindre, med Rust.

Skickades från m.sweclockers.com

Permalänk
Medlem
Skrivet av theIDinsideX:

Ett enkelt råd, ska du skriva små enkla eller mer komplexa program där socketprogrammering ingår använd inte Java. Det är alldeles för skräpigt. Använd Rust istället, det är ett mycket mer low level språk men, det har ett så mycket enklare gränssnitt samt pakethanterare för att använda tredjepartsbibliotek än Java. Något som tar 100 rader kod i Java att skriva, när det gäller detta ämnet kan du skriva med ca 10 rader om inte mindre, med Rust.

Skickades från m.sweclockers.com

Håller med, detta är inget man vill koda "manuellt" annat än för att det är kul. Om det är en seriös applikation bör ts kolla in något bibliotek på den plattform han jobbar på.

Permalänk
Skrivet av theIDinsideX:

Ett enkelt råd, ska du skriva små enkla eller mer komplexa program där socketprogrammering ingår använd inte Java. Det är alldeles för skräpigt. Använd Rust istället, det är ett mycket mer low level språk men, det har ett så mycket enklare gränssnitt samt pakethanterare för att använda tredjepartsbibliotek än Java. Något som tar 100 rader kod i Java att skriva, när det gäller detta ämnet kan du skriva med ca 10 rader om inte mindre, med Rust.

Skickades från m.sweclockers.com

Boo, Go, Rust....Ja alla dessa små wannabe C-språk har ändå ingen framtid. Så länge det inte finns ett sätt för Rust att ersätta C så finns det ingen anledning att använda Rust. Tro mig, industrin använder inte C och Java bara för att det är kul, utan för att dom fungerar och är anpassade för industrin.

Många androidutvecklare har gått från Java -> Kotlin. Men denna period lär inte vara långvarig med tanke på att Java är snabbare än Kotlin hos Android.

Språk som man skriver mycket kod i t.ex. C, C++, Java, C# osv brukar generellt vara bättre språk än Python, Ruby, PHP, Rust för man har mer kontroll och kan optimera koden bättre. Men är det ont om tid och prestanda är inte fokus, så kanske Python är det enda alternativet.

Permalänk
Medlem
Skrivet av heretic16:

Boo, Go, Rust....Ja alla dessa små wannabe C-språk har ändå ingen framtid. Så länge det inte finns ett sätt för Rust att ersätta C så finns det ingen anledning att använda Rust. Tro mig, industrin använder inte C och Java bara för att det är kul, utan för att dom fungerar och är anpassade för industrin.

Många androidutvecklare har gått från Java -> Kotlin. Men denna period lär inte vara långvarig med tanke på att Java är snabbare än Kotlin hos Android.

Språk som man skriver mycket kod i t.ex. C, C++, Java, C# osv brukar generellt vara bättre språk än Python, Ruby, PHP, Rust för man har mer kontroll och kan optimera koden bättre. Men är det ont om tid och prestanda är inte fokus, så kanske Python är det enda alternativet.

Jag tror du blandar ihop Rust med nåt annat språk.

Medan rust må kunna se väldigt hög-nivå ut, då och då, så är det helt inkorrekt att likaställa med scriptspråk som Python och PHP. Rust börjar på ungefär samma nivå som C, med pekare och grejer, men med hjälp av smarta abstraktioner kan man ofta arbeta på en högre nivå utan att offra prestanda. Faktum är att Rust i regel har lika bra prestanda som C, men tack vare ett mycket bättre typsystem så är det faktiskt enklare att skriva snabb kod i Rust än i C ibland. Se till exempel http://dtrace.org/blogs/bmc/2018/09/28/the-relative-performance-of-c-and-rust/

Skickades från m.sweclockers.com

Visa signatur

Arbets- / Spelstation: Arch Linux - Ryzen 5 3600 - RX 7900 XT - 32G DDR4
Server: Arch Linux - Core i5-10400F - 16G DDR4

Permalänk
Skrivet av Bryal:

Jag tror du blandar ihop Rust med nåt annat språk.

Medan rust må kunna se väldigt hög-nivå ut, då och då, så är det helt inkorrekt att likaställa med scriptspråk som Python och PHP. Rust börjar på ungefär samma nivå som C, med pekare och grejer, men med hjälp av smarta abstraktioner kan man ofta arbeta på en högre nivå utan att offra prestanda. Faktum är att Rust i regel har lika bra prestanda som C, men tack vare ett mycket bättre typsystem så är det faktiskt enklare att skriva snabb kod i Rust än i C ibland. Se till exempel http://dtrace.org/blogs/bmc/2018/09/28/the-relative-performance-of-c-and-rust/

Skickades från m.sweclockers.com

Om Rust ska vara en ersättare av C, varför har vi inte sett industrin ändra på sig? Jag menar, Rust har varit med om ett bra tag nu. Det borde komma ny hårdvara som ger sin support till Rust.

Permalänk
Medlem

Vad är det för program du försöker åstadkomma? Vad är syftet med det?

Visa signatur

WS: Mac Studio M1 Max | 32 GB | 1TB | Mac OS
WS: Intel i5 12600K | 64 GB DDR4 @3600 Mhz | 2x1TB nvme 2x1TB SSD SATA | Windows 11 & Manjaro Linux
Bärbar: Macbook Pro 14" | M1 Pro | 16GB RAM | 512GB SSD | Mac OS
Servrar: Intel i7 10700K | 64 GB DDR4 @3600Mhz | 3 TB SSD + 22TB HDD | Unraid |
4x Raspberry pi 4b 8Gb | Dietpi |

Permalänk
Datavetare

Finns ett protokoll som är specifikt designat för exakt vad du försöker göra: MQTT.

MQTT bibliotek finns för i princip alla populära språk, inklusive Java!

MQTT fixar saker som publicera ett meddelande till noll eller flera klienter, man kan sätta quality-of-service nivå, det har hantering för om en maskin tappar nätverksanslutning etc.

Att göra det du vill direkt med sockets är lite som att skriva en webbapplikation i assembler...

I Python >=3.7 skulle det då blir något åt detta håll

import asyncio import hbmqtt.client as mqtt from hbmqtt.mqtt.constants import QOS_1 def octaveSet(input_signal, output_signal, time): print('input_signal = {}, output_signal = {}, time = {}' .format(input_signal, output_signal, time)) async def octaveGet(broker): # Get the actual data here payload = 'Time#PwmStartSignal#ReferencePoint#Horizon#SensorSlope#SensorOffset#Running' await broker.publish('octave/val', payload.encode()) async def run(): broker = mqtt.MQTTClient() await broker.connect('mqtt://localhost/') await broker.subscribe([ ('octave/get', QOS_1), ('octave/set', QOS_1), ('android/get', QOS_1), ('android/set', QOS_1), ('control/disconnect', QOS_1), ]) connected = True while connected: message = await broker.deliver_message() packet = message.publish_packet topic = packet.variable_header.topic_name payload: str = packet.payload.data.decode() if topic == 'control/disconnect': connected = False elif topic == 'octave/set': octaveSet(*payload.split('#')) elif topic == 'octave/get': await octaveGet(broker) # elif the rest... if __name__ == '__main__': asyncio.run(run())

Använder inte du en RPi3 för detta projekt? i så fall, varför Java? Python (som för övrigt är det språk som är världens populäraste i många mätningar, bl.a. mest populära inom undervisning) är ju ett av de språk som har riktigt bra stöd på RPi, C och C++ har naturligtvis också fullt stöd.

Rekommenderar Mosquitto som MQTT broker. Finns som färdigt paket till RPi (och till i princip alla Linux distron).

BTW: Tror du har helt fel om Kotlin. Dels är inte Kotlin långsammare än Java om man gör samma sak, faktum är att vid funktionell programmering är typiskt Kotlin snabbare då det har lite trick som "inline". Nu gör Kotlin det möjligt att skriva saker på en högre nivå, det kan i sig leda till lösningar som är lite långsammare.

Men dels så är Googles val av Kotlin som nytt primärspråk i Android mycket en reaktion på att Oracle stämt Android för dess användning av Java. Google vill komma bort från Java då det inte är trevligt att ha Oracles advokater hängande efter sig!

Personligen tycket jag att Kotlin är "Java done right!".

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

Finns ett protokoll som är specifikt designat för exakt vad du försöker göra: MQTT.

MQTT bibliotek finns för i princip alla populära språk, inklusive Java!

MQTT fixar saker som publicera ett meddelande till noll eller flera klienter, man kan sätta quality-of-service nivå, det har hantering för om en maskin tappar nätverksanslutning etc.

Att göra det du vill direkt med sockets är lite som att skriva en webbapplikation i assembler...

I Python >=3.7 skulle det då blir något åt detta håll

import asyncio import hbmqtt.client as mqtt from hbmqtt.mqtt.constants import QOS_1 def octaveSet(input_signal, output_signal, time): print('input_signal = {}, output_signal = {}, time = {}' .format(input_signal, output_signal, time)) async def octaveGet(broker): # Get the actual data here payload = 'Time#PwmStartSignal#ReferencePoint#Horizon#SensorSlope#SensorOffset#Running' await broker.publish('octave/val', payload.encode()) async def run(): broker = mqtt.MQTTClient() await broker.connect('mqtt://localhost/') await broker.subscribe([ ('octave/get', QOS_1), ('octave/set', QOS_1), ('android/get', QOS_1), ('android/set', QOS_1), ('control/disconnect', QOS_1), ]) connected = True while connected: message = await broker.deliver_message() packet = message.publish_packet topic = packet.variable_header.topic_name payload: str = packet.payload.data.decode() if topic == 'control/disconnect': connected = False elif topic == 'octave/set': octaveSet(*payload.split('#')) elif topic == 'octave/get': await octaveGet(broker) # elif the rest... if __name__ == '__main__': asyncio.run(run())

Använder inte du en RPi3 för detta projekt? i så fall, varför Java? Python (som för övrigt är det språk som är världens populäraste i många mätningar, bl.a. mest populära inom undervisning) är ju ett av de språk som har riktigt bra stöd på RPi, C och C++ har naturligtvis också fullt stöd.

Rekommenderar Mosquitto som MQTT broker. Finns som färdigt paket till RPi (och till i princip alla Linux distron).

BTW: Tror du har helt fel om Kotlin. Dels är inte Kotlin långsammare än Java om man gör samma sak, faktum är att vid funktionell programmering är typiskt Kotlin snabbare då det har lite trick som "inline". Nu gör Kotlin det möjligt att skriva saker på en högre nivå, det kan i sig leda till lösningar som är lite långsammare.

Men dels så är Googles val av Kotlin som nytt primärspråk i Android mycket en reaktion på att Oracle stämt Android för dess användning av Java. Google vill komma bort från Java då det inte är trevligt att ha Oracles advokater hängande efter sig!

Personligen tycket jag att Kotlin är "Java done right!".

Jag tycker Kotlin är Javas svar (eller är det IntelliJ svar?) på C#. I princip alla bra features från C# inklämda i Java.

Skrivet av heretic16:

Boo, Go, Rust....Ja alla dessa små wannabe C-språk har ändå ingen framtid. Så länge det inte finns ett sätt för Rust att ersätta C så finns det ingen anledning att använda Rust. Tro mig, industrin använder inte C och Java bara för att det är kul, utan för att dom fungerar och är anpassade för industrin.

Många androidutvecklare har gått från Java -> Kotlin. Men denna period lär inte vara långvarig med tanke på att Java är snabbare än Kotlin hos Android.

Språk som man skriver mycket kod i t.ex. C, C++, Java, C# osv brukar generellt vara bättre språk än Python, Ruby, PHP, Rust för man har mer kontroll och kan optimera koden bättre. Men är det ont om tid och prestanda är inte fokus, så kanske Python är det enda alternativet.

Varför är du alltid en sådan Java riddare? Alla språk har nackelar och fördelar och är bra för att lösa olika problem. Det finns inget enstaka språk som är bäst på allt och det är definitivt inte Java. Om jag har en verktygslåda med en bra hammare betyder inte det att jag försöker skruva i en skruv med den, det blir inte bra hur jag än gör.

Permalänk
Datavetare
Skrivet av Baxtex:

Jag tycker Kotlin är Javas svar (eller är det IntelliJ svar?) på C#. I princip alla bra features från C# inklämda i Java.

Kotlin kommer från JetBrains som ligger bakom IntelliJ. Men numera har Google också egna team som jobbar med att utveckla Kotlin, språket är ju "öppet" så alla kan vara med.

Håller med om att C# som språk är bättre än Java och att Kotlin är mer likt C#. Fast även med min rätt begränsade Kotlin kunskaper är det uppenbart att Kotlin har en rad riktigt trevliga egenskaper som C# (än så länge) saknar. Den överlägset viktigaste är att Kotlin är ett multiparadigm språk som stödjer topp-nivå funktioner.

Givet hur mycket trevligare Kotlin är samt att det är helt kompatibelt med saker skrivet i Java blir man lite fundersam varför språket verkar ha relativt lågt genomslag utanför Android än så länge. Men kanske bara jag som inte har koll på hur dessa användning är fördelad?

Sedan finns det alltid väldig mycket tröghet i val av språk. Så inget konstigt att Java, C och JavaScript fortsätter ligga i topp mest använda språk trots att alla har alternativ som på de flesta sätt nog är tekniskt mer lämpade idag. Rust nämndes ovan, det är ett språk som man tittar på nu i fall som bara inte får gå fel, dessa använder idag nästan alltid C... Så Rust kan bli populärt där, men eventuellt övergång kommer ta lång tid!

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem

@heretic16:
Du skickar aldrig någon data.

/* * Send now to our client */ System.out.println(send); bufferedWriter.write(send.length()); // We first send length bufferedWriter.write(send); break;

BufferedWriter sparar det du skriver med write(c: Int) / write(s: String) i en intern Char array av storlek 8192 (kan ändras i konstruktorn). Det är först när bufferten blir full eller du anropar BufferedWriter::flush som det du skrivit skickas vidare.

Det finns andra problem också i koden du har postat.
Alla klienter (trådar) delar på samma Storage. Vad händer om flera klienter samtidigt anropar storage.get* / storage.set* funktioner?
Hur man delar data mellan olika trådar på ett korrekt sätt är inte helt självklart. Enklaste lösningen i ditt exempel är att använda synchronized (Object) { } runt den kod som du vill att bara en tråd åt gången ska ha tillgång till.

Du missar att stänga streams. Använd try-with-resources:

try( var is = socket.getInputStream(); var os = socket.getOutputStream() ) { // använd is/os här } // is/os.close anropas automatiskt när blocket tar slut.

Det finns ingen anledning att skapa en en massa instansvariabler, använd lokala variabler.

Permalänk
Medlem
Skrivet av heretic16:

Om Rust ska vara en ersättare av C, varför har vi inte sett industrin ändra på sig? Jag menar, Rust har varit med om ett bra tag nu. Det borde komma ny hårdvara som ger sin support till Rust.

Rust har bara varit med några år. C har funnits i över 40 år.
Förändringar tar tid.