Swift 3 TCP Server

Swift 3 TCP Server
2018-09-04T11:11:04+02:00
2018-09-05T12:42:57+02:00
2022-10-15T21:35:50+02:00
szotyi
Sziasztok!

Szeretnek egy "egyszeru" TCP server programot, ami fogadja a clienteket, es visszakuldi a clientnek azt az uzenetet amit kapott tole.

Jelenleg itt tartok:
GitHub - swiftsocket/SwiftSocket: The easy way to use sockets on Apple platforms

import UIKit import SwiftSocket class ViewController: UIViewController { var client: TCPClient? let formatter = DateFormatter() override func viewDidLoad() { super.viewDidLoad() formatter.dateFormat = "HH:mm:ss.SSS" testServer() } func echoService(client: TCPClient) { print("Newclient from:\(client.address)[\(client.port)]") while true { // print() let number1: Int32 = client.bytesAvailable()! let number2 = Int(number1) var d = client.read(number2) if d != nil { print(self.formatter.string(from: Date()), " ", terminator:"") print(String(data: Data(d!), encoding: .utf8)) client.send(data: d!) } } } func testServer() { let server = TCPServer(address: "192.168.1.102", port: 3456) switch server.listen() { case .success: print("success") while true { print("loop") if var client = server.accept() { echoService(client: client) } else { print("accept error") } } case .failure(let error): print(error) } } }
Ez megy is, csak ket problemam van vele:
Csak egy client-el mukodik, illetve, hogy 100% CPU-al hasit.
Tudna nekem valaki segiteni? 

Koszonom elore is!
Mutasd a teljes hozzászólást!
Nem tudok Swift-ül, de látszólag egészen kevés hiányzik a kívánt működéshez.
A 100%-os CPU-használat elkerüléséhez valami ilyesmi kéne:

var d = client.read(1) var d1 = client.read(client.bytesAvailable())
ekkor a program (később meg szál) megáll addig, amíg legalább egy byte-ot be nem tud olvasni (a "d"-be), és a fennmaradó byte-okat meg beolvassa a d1-be. Látom, hogy a bytesAvailable Int32-t ad vissza, a read meg Int-et vár, szóval lehet, hogy kell bele egy Int()-ezés, fogalmam sincs.
A másik meg, hogy így az üzenet első byte-ja külön van, és jönne az összefűzés. Még mindig nem tudok Swift-ül, de állítólag egy sima + jel megoldja.
Szóval összességében lehet, hogy ez az egy sor kéne neked:

var d = client.read(1) + client.read(Int(client.bytesAvailable)))
Vagy nem.

A Swift-es szálazáshoz szintén nem konyítok, de innen: Swift tcp multithread server  nézve a mintát, nagyon közel jársz, csak a közvetlen echoService-hívás helyett valami ilyesmi kéne:

var thread : NSThread = NSThread(target:self, selector:Selector("echoService:"), object:client) thread.start()
Lehet, hogy kell még a "dynamic" a "func echoService(...)" elé, ezt látom a példában, de nem tudom, hogy mit jelent.
Mutasd a teljes hozzászólást!

  • Több kliens egyidejű kezelését szálakkal, vagy select-ekkel szokás megoldani. Hiszen jelenleg accept után belépsz az echoService függvényben található ciklusba, és amíg az fut, újabb accept-re nem kerül a vezérlés. Ha a kliensed lekapcsolódik, lehet, hogy valamilyen kivétellel kilép a ciklusból (pl. SwiftSocket/TCPClient.swift at master · swiftsocket/SwiftSocket  miatt), ezt ki kéne próbálni. Utána egy másik kliens elvileg újra kapcsolódhatna.
    A processzorhasználatot meg pont az a bytesAvailable-read ciklus oldja meg: a bytesAvailable 0-val is visszatérhet, ilyenkor foglalsz egy 0 byte-os tömböt, majd teleolvasod, és ez ismétlődik.
    Ezt a rész úgy tudnád megoldani, hogy egy byte-ot mindenképpen olvasol, utána nézel bytesAvailable-t, és olvasod ki a maradékot. Utána persze ne felejtsd el az elején olvasott byte-ot hozzáfűzni az üzenethez, bár első próbálkozásra azt is ki lehet bírni, ha egy "Hello vilag!"-ból csak "ello vilag!" jön vissza.
    Mutasd a teljes hozzászólást!
  • koszi!
    Mutasd a teljes hozzászólást!
  • Nem tudok Swift-ül, de látszólag egészen kevés hiányzik a kívánt működéshez.
    A 100%-os CPU-használat elkerüléséhez valami ilyesmi kéne:

    var d = client.read(1) var d1 = client.read(client.bytesAvailable())
    ekkor a program (később meg szál) megáll addig, amíg legalább egy byte-ot be nem tud olvasni (a "d"-be), és a fennmaradó byte-okat meg beolvassa a d1-be. Látom, hogy a bytesAvailable Int32-t ad vissza, a read meg Int-et vár, szóval lehet, hogy kell bele egy Int()-ezés, fogalmam sincs.
    A másik meg, hogy így az üzenet első byte-ja külön van, és jönne az összefűzés. Még mindig nem tudok Swift-ül, de állítólag egy sima + jel megoldja.
    Szóval összességében lehet, hogy ez az egy sor kéne neked:

    var d = client.read(1) + client.read(Int(client.bytesAvailable)))
    Vagy nem.

    A Swift-es szálazáshoz szintén nem konyítok, de innen: Swift tcp multithread server  nézve a mintát, nagyon közel jársz, csak a közvetlen echoService-hívás helyett valami ilyesmi kéne:

    var thread : NSThread = NSThread(target:self, selector:Selector("echoService:"), object:client) thread.start()
    Lehet, hogy kell még a "dynamic" a "func echoService(...)" elé, ezt látom a példában, de nem tudom, hogy mit jelent.
    Mutasd a teljes hozzászólást!
  • Koszonom, igy mukodik!
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd