Java Programiranje - Klijent-server zadatak

El_dabaco

Obećava
Poruka
55
Pozdrav narode, može li pomoć oko ovog zadatka?Hitno je. Ne znam iz kog razloga, ali dođem do dela kada ukucam 2 broja, ali ih ne prikaže na serveru. Ako bi neko mogao da mi pomogne bio bih mu zahvalan. Hvala unapred.

U pitanju je sledeći zadatak:
Potrebno je kreirati aplikaciju za sabiranje dva broja. Sama operacija sabiranja treba da se odigra na serveru, koji prihvata dva sabirka i isporučuje rezultat. Stoga je neophodno da rešenje sadrži dve komponente: serversku i klijentsku.

Unutar klijentske aplikacije, korisniku je potrebno omogućiti da unese dva broja korišćenjem Scanner klase. Vrednosti je potrebno smestiti unutar promenljivih, a zatim poslati serverskom delu aplikacije. Vrednosti se mogu poslati objedinjeno ili zasebno. Nakon prihvatanja vrednosti, server treba da obavi sabiranje prosleđenih brojeva i da klijentu isporuči dobijeni zbir. Dobijeni zbir je na klijentu potrebno prikazati na izlazu.

Evo i koda.

SERVER:

Java:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class server {
    public static void main(String[] args) {
        System.out.println("Listening");

        try(ServerSocket serverSocket = new ServerSocket(1080);
            Socket socket = serverSocket.accept();
            BufferedReader bis = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream())){


            String line = bis.readLine();

            bos.write(("Rezultat je:" + line).getBytes());
            bos.flush();

        }catch (IOException ie){
            System.out.println(ie.getMessage());
        }
    }
}





KLIJENT:
Java:
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.Scanner;

public class client {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter first number: ");
        int a = sc.nextInt();
        System.out.println("Enter second number: ");
        int b = sc.nextInt();
        int sum = a+b;

        try(Socket socket = new Socket("localhost", 1080);
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream())){

            bos.write(sum);
            bos.flush();

            String line = br.readLine();
            System.out.println(line);

        }catch(IOException io){
            System.out.println(io.getMessage());
        }
    }
}
 
Evo ti u Swiftu sto je mnogo teze od Jave posto nema Socket klase nego je tanak
wrapper oko BSD soketa :P
klijent:
Swift:
import Foundation

let c = Client();
c.start()

class Client {

  let servicePort = "1234"

  func start() {
    print("Client starting...")
    print("unesi prvi broj")
    let num1 = Int(readLine()!)
    print("unesi drugi broj")
    let num2 = Int(readLine()!)


    let socketFD = socket(AF_INET6, //Domain [AF_INET,AF_INET6, AF_UNIX]
                          SOCK_STREAM, //Type [SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW]
                          IPPROTO_TCP  //Protocol [IPPROTO_TCP, IPPROTO_SCTP, IPPROTO_UDP, IPPROTO_DCCP]
                          )//Return a FileDescriptor -1 = error
    if socketFD == -1 {
      print("Error creating BSD Socket")
      return
    }

    var hints = addrinfo(
      ai_flags: AI_PASSIVE,       // Assign the address of the local host to the socket structures
      ai_family: AF_UNSPEC,       // Either IPv4 or IPv6
      ai_socktype: SOCK_STREAM,   // TCP
      ai_protocol: 0,
      ai_addrlen: 0,
      ai_canonname: nil,
      ai_addr: nil,
      ai_next: nil)

    var servinfo: UnsafeMutablePointer<addrinfo>? = nil
    let addrInfoResult = getaddrinfo(
      nil,                        // Any interface
      servicePort,                   // The port on which will be listenend
      &hints,                     // Protocol configuration as per above
      &servinfo)

    if addrInfoResult != 0 {
      print("Error getting address info: \(errno)")
      return
    }

    let connectResult = connect(socketFD, servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))

    if connectResult == -1 {
      print("Error connecting socket to Address: \(errno)")
      return
    }


      let MTU = 65536
//      var addr = sockaddr()
//      var addr_len :socklen_t = 0


      let buffer = UnsafeMutablePointer<CChar>.allocate(capacity: MTU)
      defer {
        buffer.deallocate()
      }
      let s = String(format: "%d %d",num1!,num2!)
      let _ = s.withCString{
          write(socketFD, $0, s.count+1)
        }
        let readResult = read(socketFD, buffer, MTU)

        if (readResult == 0) {
          print("server closed")
        } else if (readResult == -1) {
          print("Error reading form server\(socketFD) - \(errno)")
        } else {
          let strResult =
              String(cString: buffer)
          print("Received form server(\(socketFD)): \(strResult)")
        }
  }

}
server:
Swift:
import Foundation

let s = Server();
s.start()

class Server {

  let servicePort = "1234"

  func start() {
    print("Server starting...")

    let socketFD = socket(AF_INET6, //Domain [AF_INET,AF_INET6, AF_UNIX]
                          SOCK_STREAM, //Type [SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW]
                          IPPROTO_TCP  //Protocol [IPPROTO_TCP, IPPROTO_SCTP, IPPROTO_UDP, IPPROTO_DCCP]
                          )//Return a FileDescriptor -1 = error
    if socketFD == -1 {
      print("Error creating BSD Socket")
      return
    }

    var hints = addrinfo(
      ai_flags: AI_PASSIVE,       // Assign the address of the local host to the socket structures
      ai_family: AF_UNSPEC,       // Either IPv4 or IPv6
      ai_socktype: SOCK_STREAM,   // TCP
      ai_protocol: 0,
      ai_addrlen: 0,
      ai_canonname: nil,
      ai_addr: nil,
      ai_next: nil)

    var servinfo: UnsafeMutablePointer<addrinfo>? = nil
    let addrInfoResult = getaddrinfo(
      nil,                        // Any interface
      servicePort,                   // The port on which will be listenend
      &hints,                     // Protocol configuration as per above
      &servinfo)

    if addrInfoResult != 0 {
      print("Error getting address info: \(errno)")
      return
    }

    let bindResult = bind(socketFD, servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))

    if bindResult == -1 {
      print("Error binding socket to Address: \(errno)")
      return
    }

    let listenResult = listen(socketFD, //Socket File descriptor
                              8         // The backlog argument defines the maximum length the queue of pending connections may grow to
    )

    if listenResult == -1 {
      print("Error setting our socket to listen")
      return
    }

    while (true) {
      let MTU = 65536
      var addr = sockaddr()
      var addr_len :socklen_t = 0

      print("About to accept")
      let clientFD = accept(socketFD, &addr, &addr_len)
      defer {
        close(clientFD)
      }
      print("Accepted new client with file descriptor: \(clientFD)")

      if clientFD == -1 {
        print("Error accepting connection")
      }
      let buffer = UnsafeMutablePointer<CChar>.allocate(capacity:MTU)
      defer {
         buffer.deallocate()
      }
      while(true) {
        let readResult = read(clientFD, buffer, MTU)

        if (readResult == 0) {
          break;  // end of file
        } else if (readResult == -1) {
          print("Error reading form client\(clientFD) - \(errno)")
          break;  // error
        } else {
          let strResult =
              String(cString: buffer)
          let numbers = strResult.components(separatedBy: " ")
          let num1 = Int(numbers[0])
          let num2 = Int(numbers[1])
          let sum = num1!+num2!

          print("Received form client(\(clientFD)): \(strResult)")
          let out = String(format:"suma %d",sum)
          let _ = out.withCString {
            write(clientFD, $0, out.count)
          }
        }
      }
    }
  }

}

I izvrsavanje:
Kod:
bmaxa@Branimirs-Air fileio % ./sumServer
Server starting...
About to accept
Accepted new client with file descriptor: 5
Received form client(5): 5 7
About to accept
bmaxa@Branimirs-Air fileio % ./sumClient
Client starting...
unesi prvi broj
5
unesi drugi broj
7
Received form server(3): suma 12
Mislim da ti nece biti problem da pretabas u Javu :P
 
A evo ti i napredniji server koji moze vise klijenata da opsluzi, ovo je veoma slicno Javi:
Swift:
import Foundation

let s = Server();
s.start()

class Server {

  let servicePort = "1234"
  class Worker:Thread{
    init(_ fd:Int32){
      self.fd = fd
    }
    deinit {
        close(fd)
    }
    override func main(){
      let MTU = 65536
      let buffer = UnsafeMutablePointer<CChar>.allocate(capacity:MTU)
      defer {
         buffer.deallocate()
      }
      while(true) {
        let readResult = read(fd, buffer, MTU)

        if (readResult == 0) {
          break;  // end of file
        } else if (readResult == -1) {
          print("Error reading form client\(fd) - \(errno)")
          break;  // error
        } else {
          let strResult =
              String(cString: buffer)
          let numbers = strResult.components(separatedBy: " ")
          var sum = 0
          if numbers.count > 1 {
            let num1:Int? = Int(numbers[0])
            let num2:Int? = Int(numbers[1])
            let num11 = num1 ?? 0
            let num22 = num2 ?? 0
            sum = num11 + num22
          }
          print("Received form client(\(fd)): \(strResult)")
          let out = String(format:"suma %d\n",sum)
          let _ = out.withCString {
            write(fd, $0, out.count)
          }
        }
      }
    }
    var fd: Int32
  }
  func start() {
    print("Server starting...")

    let socketFD = socket(AF_INET6, //Domain [AF_INET,AF_INET6, AF_UNIX]
                          SOCK_STREAM, //Type [SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW]
                          IPPROTO_TCP  //Protocol [IPPROTO_TCP, IPPROTO_SCTP, IPPROTO_UDP, IPPROTO_DCCP]
                          )//Return a FileDescriptor -1 = error
    if socketFD == -1 {
      print("Error creating BSD Socket")
      return
    }

    var hints = addrinfo(
      ai_flags: AI_PASSIVE,       // Assign the address of the local host to the socket structures
      ai_family: AF_UNSPEC,       // Either IPv4 or IPv6
      ai_socktype: SOCK_STREAM,   // TCP
      ai_protocol: 0,
      ai_addrlen: 0,
      ai_canonname: nil,
      ai_addr: nil,
      ai_next: nil)

    var servinfo: UnsafeMutablePointer<addrinfo>? = nil
    let addrInfoResult = getaddrinfo(
      nil,                        // Any interface
      servicePort,                   // The port on which will be listenend
      &hints,                     // Protocol configuration as per above
      &servinfo)

    if addrInfoResult != 0 {
      print("Error getting address info: \(errno)")
      return
    }

    let bindResult = bind(socketFD, servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))

    if bindResult == -1 {
      print("Error binding socket to Address: \(errno)")
      return
    }

    let listenResult = listen(socketFD, //Socket File descriptor
                              8         // The backlog argument defines the maximum length the queue of pending connections may grow to
    )

    if listenResult == -1 {
      print("Error setting our socket to listen")
      return
    }

    while (true) {
      var addr = sockaddr()
      var addr_len :socklen_t = 0

      print("About to accept")
      let clientFD = accept(socketFD, &addr, &addr_len)
      print("Accepted new client with file descriptor: \(clientFD)")

      if clientFD == -1 {
        print("Error accepting connection")
      }
      let handle = Worker(clientFD);
      handle.start()
    }
  }

}
 
Naprednija verzija, posle idemo na kqueue :P
Swift:
import Foundation
signal(SIGPIPE,SIG_IGN)
let s = Server();
s.start()
var ende:Bool? = nil
var semacnt:Int? = nil
var mutex:Bool? = nil
var accarrFD:[Int32]? = nil
class Server {
  init() {
    if (CommandLine.argc > 1) {
      tmpSvcPort = Int(CommandLine.arguments[1]) ?? 0
      if (tmpSvcPort > 0){ servicePort = String(tmpSvcPort) }
    }
    semacnt! = 0
    mutex! = false
    ende! = false
    accarrFD! = Array(repeating:Int32(0),count:0)
  }
  var tmpSvcPort: Int = 0
  var servicePort = "1234"
  class Worker:Thread{
    init(_ fd:Int32){
      self.fd = fd
      semacnt! += 1
    }
    deinit {
      semacnt! -= 1
    }
    override func main(){
      let MTU = 65536
      let buffer = UnsafeMutablePointer<CChar>.allocate(capacity:MTU)
      defer {
         buffer.deallocate()
      }
      while (mutex! == true){usleep(100)}
      mutex! = true
      print("acquired")
      var oneFD = Array(repeating:Int32(0),count:0)
      while (!accarrFD!.isEmpty){
        /// collect rest of fds
        oneFD.append(accarrFD![accarrFD!.count-1])
        accarrFD!.remove(at:accarrFD!.count-1)
      }
      mutex! = false /// seems we do not need barrier
      print("releazed\n")
      var toproc = [fd]
      toproc += oneFD
      for fd in toproc{
        defer {close(fd)}
        let readResult = read(fd, buffer, MTU)

        if (readResult == 0) {
          break;  // end of file
        } else if (readResult == -1) {
          print("Error reading form client(\(fd)) - \(errno)")
          break;  // error
        } else {
          let strResult =
              String(cString: buffer)
          let cset = CharacterSet(charactersIn: " \r\n")
          let numbers = strResult.components(separatedBy: cset)
          var sum = 0
          if numbers.count > 1 {
            if numbers[0].lowercased() == "quit" {
              ende! = true
              continue
            } else {
              let num1 = Int(numbers[0]) ?? 0
              let num2 = Int(numbers[1]) ?? 0
              sum = num1 + num2
            }
          }
          print("Received form client(\(fd)): \(strResult)")
          let out = String(format:"suma %d\n",sum)
          let _ = out.withCString {
             /**let flags = fcntl(fd,F_GETFL)
             let _ = fcntl(fd,F_SETFL,flags | O_NONBLOCK)
             */
             while(semacnt! > 128){usleep(100)}
             write(fd, $0, out.count)

          }
        }
      }
    }
    var fd: Int32
  }
  func start() {
    print("Server starting...")

    let socketFD = socket(AF_INET6, //Domain [AF_INET,AF_INET6, AF_UNIX]
                          SOCK_STREAM, //Type [SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW]
                          IPPROTO_TCP  //Protocol [IPPROTO_TCP, IPPROTO_SCTP, IPPROTO_UDP, IPPROTO_DCCP]
                          )//Return a FileDescriptor -1 = error
    if socketFD == -1 {
      print("Error creating BSD Socket")
      return
    }

    var hints = addrinfo(
      ai_flags: AI_PASSIVE,       // Assign the address of the local host to the socket structures
      ai_family: AF_UNSPEC,       // Either IPv4 or IPv6
      ai_socktype: SOCK_STREAM,   // TCP
      ai_protocol: 0,
      ai_addrlen: 0,
      ai_canonname: nil,
      ai_addr: nil,
      ai_next: nil)

    var servinfo: UnsafeMutablePointer<addrinfo>? = nil
    let addrInfoResult = getaddrinfo(
      nil,                        // Any interface
      servicePort,                   // The port on which will be listenend
      &hints,                     // Protocol configuration as per above
      &servinfo)

    if addrInfoResult != 0 {
      print("Error getting address info: \(errno)")
      return
    }
    setsockopt(socketFD,SOL_SOCKET,SO_REUSEADDR,servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))
    let bindResult = bind(socketFD, servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))

    if bindResult == -1 {
      print("Error binding socket to Address: \(errno)")
      return
    }

    let listenResult = listen(socketFD, //Socket File descriptor
                              128         // The backlog argument defines the maximum length the queue of pending connections may grow to
    )

/**    let flags = fcntl(socketFD,F_GETFL)
    let _ = fcntl(socketFD,F_SETFL,flags | O_NONBLOCK)
*/

    if listenResult == -1 {
      print("Error setting our socket to listen")
      return
    }
    while (!ende!) {
      var addr = sockaddr()
      var addr_len :socklen_t = 0
      while (!ende!) {
          print("About to accept")
          let accFD = accept(socketFD, &addr, &addr_len)
          if (accFD > 0){
              print("Accepted new client with file descriptor: \(accFD)")
              if (semacnt! < 5) {
                let handle = Worker(accFD);
                handle.start()
              } else {
                while (mutex! == true){usleep(100)}
                mutex! = true /// works fine without barrier
                accarrFD!.append(accFD)
                mutex! = false
              }
            } else {
                print("Error accepting connection")
                usleep(100)
            }
            OSMemoryBarrier() /// barrier needed here
        }
    }
  }

}
 
Evo ga zavrshen server za macOS sa M1 procesorom :P
Swift:
import Foundation
signal(SIGPIPE,SIG_IGN)
let s = Server();
s.start()
var bval:UnsafeMutablePointer<UnsafeMutableRawPointer?>? = nil
var ende:Bool? = nil
var semacnt:Int? = nil
var accarrFD:[Int32]? = nil
class Server {
  init() {
    if (CommandLine.argc > 1) {
      tmpSvcPort = Int(CommandLine.arguments[1]) ?? 0
      if (tmpSvcPort > 0){ servicePort = String(tmpSvcPort) }
    }
    semacnt! = 0
    ende! = false
    accarrFD! = Array(repeating:Int32(0),count:0)
    bval = UnsafeMutablePointer.allocate(capacity:1)
    bval!.pointee = UnsafeMutableRawPointer.allocate(byteCount:1,alignment:1)
    print("assigning")
    bval!.pointee!.storeBytes(of:0,as: UInt8.self)
    print("assigned")
  }
  deinit {
    bval!.pointee!.deallocate()
    bval!.deallocate()
  }
  var tmpSvcPort: Int = 0
  var servicePort = "1234"
  class Worker:Thread{
    override init(){
      super.init()
      semacnt! += 1
    }
    deinit {
      semacnt! -= 1
    }
    override func main(){
      let MTU = 65536
      let buffer = UnsafeMutablePointer<CChar>.allocate(capacity:MTU)
      let True = UnsafeMutablePointer<UInt8>.allocate(capacity:1)
      let False = UnsafeMutablePointer<UInt8>.allocate(capacity:1)
      True.pointee = 1
      False.pointee = 0
      defer {
        True.deallocate()
        False.deallocate()
        buffer.deallocate()
      }
      while(true){
      repeat {
        usleep(100);
        OSMemoryBarrier()
      }
      /***
       * interrestingky CAS doesn't work because of
       * some weird Apple memory scheme
      */
      while (bval!.pointee!.load(as:UInt8.self) == 1)
      OSMemoryBarrier()
      bval!.pointee!.storeBytes(of:1,as: UInt8.self)
      print("acquired")
      var oneFD = Array(repeating:Int32(0),count:0)
      if (!accarrFD!.isEmpty){
        /// collect rest of fds
        oneFD.append(accarrFD![accarrFD!.count-1])
        accarrFD!.remove(at:accarrFD!.count-1)
      }
      OSMemoryBarrier()
      bval!.pointee!.storeBytes(of:0,as: UInt8.self)
      print("releazed\n")
      let toproc = oneFD
      for fd in toproc{
        let sockKqueue = kqueue()
        if sockKqueue == -1 {
          print("Error creating kqueue")
        }

        defer {close(fd);close(sockKqueue)}
        var sockKevent = kevent(
          ident: UInt(fd),
          filter: Int16(EVFILT_READ),
          flags: UInt16(EV_ADD | EV_ENABLE),
          fflags: 0,
          data: 0,
          udata: nil)
        kevent(sockKqueue, &sockKevent, 1, nil, 0, nil)
        var event = kevent()
        let status = kevent(sockKqueue, nil, 0, &event, 1, nil)
        if  status == 0 {
          print("Timeout")
          continue
        } else if status > 0 {
            if (event.flags & UInt16(EV_EOF)) == EV_EOF {
              print("The socket (\(fd)) has been closed.")
              continue
            }
            print("File descriptor: \(fd) - has \(event.data) characters for reading")
          }
          else {
            print("Error reading kevent")
            continue
          }
        let readResult = read(fd, buffer, MTU)

        if (readResult == 0) {
          continue;  // end of file
        } else if (readResult == -1) {
          print("Error reading form client(\(fd)) - \(errno)")
          continue;  // error
        } else {
          let strResult =
              String(cString: buffer)
          let cset = CharacterSet(charactersIn: " \r\n")
          let numbers = strResult.components(separatedBy: cset)
          var sum = 0
          if numbers.count > 1 {
            if numbers[0].lowercased() == "quit" {
              ende! = true
              continue
            } else {
              let num1 = Int(numbers[0]) ?? 0
              let num2 = Int(numbers[1]) ?? 0
              sum = num1 + num2
            }
          }
          print("Received form client(\(fd)): \(strResult)")
          let out = String(format:"suma %d\n",sum)
          let _ = out.withCString {
             /**let flags = fcntl(fd,F_GETFL)
             let _ = fcntl(fd,F_SETFL,flags | O_NONBLOCK)
             */
            var sockKevent = kevent(
              ident: UInt(fd),
              filter: Int16(EVFILT_WRITE),
              flags: UInt16(EV_ADD | EV_ENABLE),
              fflags: 0,
              data: 0,
              udata: nil)
            kevent(sockKqueue, &sockKevent, 1, nil, 0, nil)
            var event = kevent()
            let status = kevent(sockKqueue, nil, 0, &event, 1, nil)
            if  status == 0 {
              print("Timeout")
            } else if status > 0 {
                if (event.flags & UInt16(EV_EOF)) == EV_EOF {
                  print("The socket (\(fd)) has been closed.")
                }
                print("File descriptor: \(fd) - can write")
                write(fd, $0, out.count)
              }
              else {
                print("Error reading kevent")
              }
            }
          }
        }
        usleep(100)
      }
    }
  }
  func start() {
    print("Server starting...")

    let socketFD = socket(AF_INET6, //Domain [AF_INET,AF_INET6, AF_UNIX]
                          SOCK_STREAM, //Type [SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW]
                          IPPROTO_TCP  //Protocol [IPPROTO_TCP, IPPROTO_SCTP, IPPROTO_UDP, IPPROTO_DCCP]
                          )//Return a FileDescriptor -1 = error
    if socketFD == -1 {
      print("Error creating BSD Socket")
      return
    }

    var hints = addrinfo(
      ai_flags: AI_PASSIVE,       // Assign the address of the local host to the socket structures
      ai_family: AF_UNSPEC,       // Either IPv4 or IPv6
      ai_socktype: SOCK_STREAM,   // TCP
      ai_protocol: 0,
      ai_addrlen: 0,
      ai_canonname: nil,
      ai_addr: nil,
      ai_next: nil)

    var servinfo: UnsafeMutablePointer<addrinfo>? = nil
    let addrInfoResult = getaddrinfo(
      nil,                        // Any interface
      servicePort,                   // The port on which will be listenend
      &hints,                     // Protocol configuration as per above
      &servinfo)

    if addrInfoResult != 0 {
      print("Error getting address info: \(errno)")
      return
    }
    setsockopt(socketFD,SOL_SOCKET,SO_REUSEADDR,servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))
    let bindResult = bind(socketFD, servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))

    if bindResult == -1 {
      print("Error binding socket to Address: \(errno)")
      return
    }

    let listenResult = listen(socketFD, //Socket File descriptor
                              128         // The backlog argument defines the maximum length the queue of pending connections may grow to
    )

/**    let flags = fcntl(socketFD,F_GETFL)
    let _ = fcntl(socketFD,F_SETFL,flags | O_NONBLOCK)
*/

    if listenResult == -1 {
      print("Error setting our socket to listen")
      return
    }
    let True = UnsafeMutablePointer<UInt8>.allocate(capacity:1)
    let False = UnsafeMutablePointer<UInt8>.allocate(capacity:1)
    True.pointee = 1
    False.pointee = 0
    defer {
      True.deallocate()
      False.deallocate()
    }
    while (!ende!) {
      var addr = sockaddr()
      var addr_len :socklen_t = 0
      while (!ende!) {
          print("About to accept")
          let accFD = accept(socketFD, &addr, &addr_len)
          if (accFD > 0){
              print("Accepted new client with file descriptor: \(accFD)")
              repeat {
                usleep(100);
                OSMemoryBarrier()
              }
              while (bval!.pointee!.load(as:UInt8.self) == 1)
              OSMemoryBarrier()
              bval!.pointee!.storeBytes(of:1,as:UInt8.self)
              accarrFD!.append(accFD)
              OSMemoryBarrier()
              bval!.pointee!.storeBytes(of:0,as:UInt8.self)
              if (semacnt! < 5) {
                let handle = Worker();
                handle.start()
              }
            } else {
                print("Error accepting connection")
                usleep(100)
            }
            OSMemoryBarrier() /// barrier needed here
        }
    }
    exit(EXIT_SUCCESS)
  }
}
 
sredjen tipi topi:
Swift:
import Foundation
signal(SIGPIPE,SIG_IGN)
let s = Server();
s.start()
var factor = 4
var bval:UnsafeMutablePointer<UnsafeMutableRawPointer?>? = nil
var ende:Bool? = nil
var semacnt:Int? = nil
var accarrFD:[Int32]? = nil
class Server {
  init() {
      let task = Process()
      task.executableURL = URL(fileURLWithPath: "/usr/sbin/sysctl")
      task.arguments = ["hw.ncpu"]
      let out = Pipe()
      task.standardOutput = out
      let res: ()? = try? task.run()
      if let _ = res {
          let outputData = out.fileHandleForReading.readDataToEndOfFile()
          let s = String(decoding: outputData, as: UTF8.self)
          print("got from sysctl ",s)
          let sep = CharacterSet(charactersIn: " \n")
          let components = s.components(separatedBy: sep)
          factor = Int(components[1]) ?? 4
      }
    if (CommandLine.argc > 1) {
      tmpSvcPort = Int(CommandLine.arguments[1]) ?? 0
      if (tmpSvcPort > 0){ servicePort = String(tmpSvcPort) }
    }
    semacnt! = 0
    ende! = false
    accarrFD! = Array(repeating:Int32(0),count:0)
    bval = UnsafeMutablePointer.allocate(capacity:1)
    bval!.pointee = UnsafeMutableRawPointer.allocate(byteCount:1,alignment:1)
    print("assigning")
    bval!.pointee!.storeBytes(of:0,as: UInt8.self)
    print("assigned")
  }
  deinit {
    bval!.pointee!.deallocate()
    bval!.deallocate()
  }
  var tmpSvcPort: Int = 0
  var servicePort = "1234"
  class Worker:Thread{
    override init(){
      super.init()
      semacnt! += 1
    }
    deinit {
      semacnt! -= 1
    }
    override func main(){
      let MTU = 65536
      let buffer = UnsafeMutablePointer<CChar>.allocate(capacity:MTU)
      defer {
        buffer.deallocate()
      }
      while(true){
      /***
       * interrestingly CAS doesn't work, because of
       * some weird Apple memory scheme.
       * OSAtomicCompareAndSwapPtr: doesn't work
      */
      usleep(1_000)
      OSMemoryBarrier()
      var val = bval!.pointee!.load(as:UInt8.self)
      if( val == 1 || val == 2 || val == 3){ continue }
      OSMemoryBarrier()
      bval!.pointee!.storeBytes(of:1,as: UInt8.self)
      OSMemoryBarrier()
      val = bval!.pointee!.load(as:UInt8.self)
      if( val == 2 || val == 3 ){ continue }
      OSMemoryBarrier()
      bval!.pointee!.storeBytes(of:2,as: UInt8.self)
      OSMemoryBarrier()
      val = bval!.pointee!.load(as:UInt8.self)
      if(val == 3){ continue }
      OSMemoryBarrier()
      bval!.pointee!.storeBytes(of:3,as: UInt8.self)
      print("acquired")
      var oneFD = Array(repeating:Int32(0),count:0)
      var acqCount = 0
      while (!accarrFD!.isEmpty && acqCount < factor*4){
        /// collect rest of fds
        acqCount += 1
        oneFD.append(accarrFD![accarrFD!.count-1])
        accarrFD!.remove(at:accarrFD!.count-1)
      }
      OSMemoryBarrier()
      bval!.pointee!.storeBytes(of:0,as: UInt8.self)
      print("releazed\n")
      let toproc = oneFD
      for fd in toproc{
          let flags = fcntl(fd,F_GETFL)
          let _ = fcntl(fd,F_SETFL,flags | O_NONBLOCK)
          
        let sockKqueue = kqueue()
        if sockKqueue == -1 {
          print("Error creating kqueue")
        }

        defer {close(fd);close(sockKqueue)}
        var sockKevent = kevent(
          ident: UInt(fd),
          filter: Int16(EVFILT_READ),
          flags: UInt16(EV_ADD | EV_ENABLE),
          fflags: 0,
          data: 0,
          udata: nil)
        kevent(sockKqueue, &sockKevent, 1, nil, 0, nil)
        var event = kevent()
        let status = kevent(sockKqueue, nil, 0, &event, 1, nil)
        if  status == 0 {
          print("Timeout")
          continue
        } else if status > 0 {
            if (event.flags & UInt16(EV_EOF)) == EV_EOF {
              print("The socket (\(fd)) has been closed.")
              continue
            }
            print("File descriptor: \(fd) - has \(event.data) characters for reading")
          }
          else {
            print("Error reading kevent")
            continue
          }
        let readResult = read(fd, buffer, MTU)

        if (readResult == 0) {
          continue;  // end of file
        } else if (readResult == -1) {
          print("Error reading form client(\(fd)) - \(errno)")
          continue;  // error
        } else {
          let strResult =
              String(cString: buffer)
          let cset = CharacterSet(charactersIn: " \r\n")
          let numbers = strResult.components(separatedBy: cset)
          var sum = 0
          if numbers.count > 1 {
            if numbers[0].lowercased() == "quit" {
              ende! = true
              continue
            } else {
              let num1 = Int(numbers[0]) ?? 0
              let num2 = Int(numbers[1]) ?? 0
              sum = num1 + num2
            }
          }
          print("Received form client(\(fd)): \(strResult)")
          let out = String(format:"suma %d\n",sum)
          let _ = out.withCString {
            var sockKevent = kevent(
              ident: UInt(fd),
              filter: Int16(EVFILT_WRITE),
              flags: UInt16(EV_ADD | EV_ENABLE),
              fflags: 0,
              data: 0,
              udata: nil)
            kevent(sockKqueue, &sockKevent, 1, nil, 0, nil)
            var event = kevent()
            let status = kevent(sockKqueue, nil, 0, &event, 1, nil)
            if  status == 0 {
              print("Timeout")
            } else if status > 0 {
                if (event.flags & UInt16(EV_EOF)) == EV_EOF {
                  print("The socket (\(fd)) has been closed.")
                }
                print("File descriptor: \(fd) - can write")
                write(fd, $0, out.count)
              }
              else {
                print("Error reading kevent")
              }
            }
          }
        }
      }
    }
  }
  func start() {
    print("Server starting...")

    let socketFD = socket(AF_INET6,    //Domain [AF_INET,AF_INET6, AF_UNIX]
                          SOCK_STREAM, //Type [SOCK_STREAM, SOCK_DGRAM,
                                       // SOCK_SEQPACKET, SOCK_RAW]
                          IPPROTO_TCP  //Protocol [IPPROTO_TCP, IPPROTO_SCTP,
                                       // IPPROTO_UDP, IPPROTO_DCCP]
                          )            //Return a FileDescriptor -1 = error
    if socketFD == -1 {
      print("Error creating BSD Socket")
      return
    }

    var hints = addrinfo(
      ai_flags: AI_PASSIVE,    // Assign the address of the local host to the
                               // socket structures
      ai_family: AF_UNSPEC,    // Either IPv4 or IPv6
      ai_socktype: SOCK_STREAM,// TCP
      ai_protocol: 0,
      ai_addrlen: 0,
      ai_canonname: nil,
      ai_addr: nil,
      ai_next: nil)

    var servinfo: UnsafeMutablePointer<addrinfo>? = nil
    let addrInfoResult = getaddrinfo(
      nil,                        // Any interface
      servicePort,                // The port on which will be listenend
      &hints,                     // Protocol configuration as per above
      &servinfo)

    if addrInfoResult != 0 {
      print("Error getting address info: \(errno)")
      return
    }
    setsockopt(socketFD,SOL_SOCKET,SO_REUSEADDR,servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))
    let bindResult = bind(socketFD, servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))

    if bindResult == -1 {
      print("Error binding socket to Address: \(errno)")
      return
    }

    let listenResult = listen(socketFD, //Socket File descriptor
                              8         // adequate
                                        // The backlog argument defines the
                                        // maximum length the queue of pending
                                        // connections may grow to
    )

    let flags = fcntl(socketFD,F_GETFL)
    let _ = fcntl(socketFD,F_SETFL,flags | O_NONBLOCK)

    let sockKqueue = kqueue()
    if sockKqueue == -1 {
        print("Error creating kqueue")
      }
      var sockKevent = kevent(
        ident: UInt(socketFD),
        filter: Int16(EVFILT_READ),
        flags: UInt16(EV_ADD | EV_ENABLE),
        fflags: 0,
        data: 0,
        udata: nil)
      kevent(sockKqueue, &sockKevent, 1, nil, 0, nil)
      var event = kevent()
      if listenResult == -1 {
      print("Error setting our socket to listen")
      return
    }
    while (!ende!) {
      var addr = sockaddr()
      var addr_len :socklen_t = 0
      while (!ende!) {
          print("About to accept")
          let status = kevent(sockKqueue, nil, 0, &event, 1, nil)
          if  status == 0 {
            print("Timeout")
            continue
          } else if status > 0 {
              if (event.flags & UInt16(EV_EOF)) == EV_EOF {
                print("The socket (\(socketFD)) has been closed.")
                continue
              }
              print("File descriptor: \(socketFD) - has \(event.data) characters for reading")
            }
            else {
              print("Error reading kevent")
              continue
            }
          let accFD = accept(socketFD, &addr, &addr_len)
          if (accFD > 0){
              print("Accepted new client with file descriptor: \(accFD)")
              OSMemoryBarrier()
              var val = bval!.pointee!.load(as:UInt8.self)
              if( val == 1 || val == 2 || val == 3){ continue }
              OSMemoryBarrier()
              bval!.pointee!.storeBytes(of:1,as: UInt8.self)
              OSMemoryBarrier()
              val = bval!.pointee!.load(as:UInt8.self)
              if( val == 3 || val == 2 ){ continue }
              OSMemoryBarrier()
              bval!.pointee!.storeBytes(of:2,as: UInt8.self)
              OSMemoryBarrier()
              val = bval!.pointee!.load(as:UInt8.self)
              if(val == 3){ continue }
              OSMemoryBarrier()
              bval!.pointee!.storeBytes(of:3,as: UInt8.self)
              accarrFD!.append(accFD)
              OSMemoryBarrier()
              bval!.pointee!.storeBytes(of:0,as:UInt8.self)
              if (semacnt! < factor) {
                let handle = Worker();
                handle.start()
              }
            } else {
                print("Error accepting connection")
            }
            usleep(1_000) // macOS tcp stack is not that good as Linux's
            OSMemoryBarrier() /// barrier needed here
        }
    }
    exit(EXIT_SUCCESS)
  }

}
 
A ovo je final, nakon tvikovanja:
Swift:
import Foundation
signal(SIGPIPE,SIG_IGN)
let s = Server();
s.start()
var factor = 4
var bval:UnsafeMutablePointer<UnsafeMutableRawPointer?>? = nil
var ende:Bool? = nil
var semacnt:Int? = nil
var accarrFD:[Int32]? = nil
class Server {
  init() {
      let task = Process()
      task.executableURL = URL(fileURLWithPath: "/usr/sbin/sysctl")
      task.arguments = ["hw.ncpu"]
      let out = Pipe()
      task.standardOutput = out
      let res: ()? = try? task.run()
      if let _ = res {
          let outputData = out.fileHandleForReading.readDataToEndOfFile()
          let s = String(decoding: outputData, as: UTF8.self)
          print("got from sysctl ",s)
          let sep = CharacterSet(charactersIn: " \n")
          let components = s.components(separatedBy: sep)
          factor = Int(components[1]) ?? 4
      }
    if (CommandLine.argc > 1) {
      tmpSvcPort = Int(CommandLine.arguments[1]) ?? 0
      if (tmpSvcPort > 0){ servicePort = String(tmpSvcPort) }
    }
    semacnt! = 0
    ende! = false
    accarrFD! = Array(repeating:Int32(0),count:0)
    bval = UnsafeMutablePointer.allocate(capacity:1)
    bval!.pointee = UnsafeMutableRawPointer.allocate(byteCount:1,alignment:1)
    print("assigning")
    bval!.pointee!.storeBytes(of:0,as: UInt8.self)
    print("assigned")
  }
  deinit {
    bval!.pointee!.deallocate()
    bval!.deallocate()
  }
  var tmpSvcPort: Int = 0
  var servicePort = "1234"
  class Worker:Thread{
    override init(){
      super.init()
      semacnt! += 1
    }
    deinit {
      semacnt! -= 1
    }
    override func main(){
      let MTU = 65536
      let buffer = UnsafeMutablePointer<CChar>.allocate(capacity:MTU)
      defer {
        buffer.deallocate()
      }
      while(true){
      usleep(1000)
      /***
       * interrestingly CAS doesn't work, because of
       * some weird Apple memory scheme.
       * OSAtomicCompareAndSwapPtr: doesn't work
      */
      var val:UInt8 = 0
      repeat {
          usleep(1)
          OSMemoryBarrier()
          val = bval!.pointee!.load(as:UInt8.self)
      }while ( val == 1 || val == 2)
      OSMemoryBarrier()
      bval!.pointee!.storeBytes(of:1,as: UInt8.self)
      repeat {
          usleep(1)
          OSMemoryBarrier()
          val = bval!.pointee!.load(as:UInt8.self)
      }while ( val == 2)
      OSMemoryBarrier()
      bval!.pointee!.storeBytes(of:2,as: UInt8.self)
      print("acquired")
      var oneFD = Array(repeating:Int32(0),count:0)
      var acqCount = 0
      while (!accarrFD!.isEmpty && acqCount < factor*4){
        /// collect rest of fds
        acqCount += 1
        oneFD.append(accarrFD![accarrFD!.count-1])
        accarrFD!.remove(at:accarrFD!.count-1)
      }
      OSMemoryBarrier()
      bval!.pointee!.storeBytes(of:0,as: UInt8.self)
      print("releazed\n")
      let toproc = oneFD
      for fd in toproc{
          let flags = fcntl(fd,F_GETFL)
          let _ = fcntl(fd,F_SETFL,flags | O_NONBLOCK)
          
        let sockKqueue = kqueue()
        if sockKqueue == -1 {
          print("Error creating kqueue")
        }

        defer {close(fd);close(sockKqueue)}
        var sockKevent = kevent(
          ident: UInt(fd),
          filter: Int16(EVFILT_READ),
          flags: UInt16(EV_ADD | EV_ENABLE),
          fflags: 0,
          data: 0,
          udata: nil)
        kevent(sockKqueue, &sockKevent, 1, nil, 0, nil)
        var event = kevent()
        let status = kevent(sockKqueue, nil, 0, &event, 1, nil)
        if  status == 0 {
          print("Timeout")
          continue
        } else if status > 0 {
            if (event.flags & UInt16(EV_EOF)) == EV_EOF {
              print("The socket (\(fd)) has been closed.")
              continue
            }
            print("File descriptor: \(fd) - has \(event.data) characters for reading")
          }
          else {
            print("Error reading kevent")
            continue
          }
        let readResult = read(fd, buffer, MTU)

        if (readResult == 0) {
          continue;  // end of file
        } else if (readResult == -1) {
          print("Error reading form client(\(fd)) - \(errno)")
          continue;  // error
        } else {
          let strResult =
              String(cString: buffer)
          let cset = CharacterSet(charactersIn: " \r\n")
          let numbers = strResult.components(separatedBy: cset)
          var sum = 0
          if numbers.count > 1 {
            if numbers[0].lowercased() == "quit" {
              ende! = true
              continue
            } else {
              let num1 = Int(numbers[0]) ?? 0
              let num2 = Int(numbers[1]) ?? 0
              sum = num1 + num2
            }
          }
          print("Received form client(\(fd)): \(strResult)")
          let out = String(format:"suma %d\n",sum)
          let _ = out.withCString {
            var sockKevent = kevent(
              ident: UInt(fd),
              filter: Int16(EVFILT_WRITE),
              flags: UInt16(EV_ADD | EV_ENABLE),
              fflags: 0,
              data: 0,
              udata: nil)
            kevent(sockKqueue, &sockKevent, 1, nil, 0, nil)
            var event = kevent()
            let status = kevent(sockKqueue, nil, 0, &event, 1, nil)
            if  status == 0 {
              print("Timeout")
            } else if status > 0 {
                if (event.flags & UInt16(EV_EOF)) == EV_EOF {
                  print("The socket (\(fd)) has been closed.")
                }
                print("File descriptor: \(fd) - can write")
                write(fd, $0, out.count)
              }
              else {
                print("Error reading kevent")
              }
            }
          }
        }
      }
    }
  }
  func start() {
    print("Server starting...")

    let socketFD = socket(AF_INET6,    //Domain [AF_INET,AF_INET6, AF_UNIX]
                          SOCK_STREAM, //Type [SOCK_STREAM, SOCK_DGRAM,
                                       // SOCK_SEQPACKET, SOCK_RAW]
                          IPPROTO_TCP  //Protocol [IPPROTO_TCP, IPPROTO_SCTP,
                                       // IPPROTO_UDP, IPPROTO_DCCP]
                          )            //Return a FileDescriptor -1 = error
    if socketFD == -1 {
      print("Error creating BSD Socket")
      return
    }

    var hints = addrinfo(
      ai_flags: AI_PASSIVE,    // Assign the address of the local host to the
                               // socket structures
      ai_family: AF_UNSPEC,    // Either IPv4 or IPv6
      ai_socktype: SOCK_STREAM,// TCP
      ai_protocol: 0,
      ai_addrlen: 0,
      ai_canonname: nil,
      ai_addr: nil,
      ai_next: nil)

    var servinfo: UnsafeMutablePointer<addrinfo>? = nil
    let addrInfoResult = getaddrinfo(
      nil,                        // Any interface
      servicePort,                // The port on which will be listenend
      &hints,                     // Protocol configuration as per above
      &servinfo)

    if addrInfoResult != 0 {
      print("Error getting address info: \(errno)")
      return
    }
    setsockopt(socketFD,SOL_SOCKET,SO_REUSEADDR,servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))
    let bindResult = bind(socketFD, servinfo!.pointee.ai_addr, socklen_t(servinfo!.pointee.ai_addrlen))

    if bindResult == -1 {
      print("Error binding socket to Address: \(errno)")
      return
    }

    let listenResult = listen(socketFD, //Socket File descriptor
                              8         // adequate
                                        // The backlog argument defines the
                                        // maximum length the queue of pending
                                        // connections may grow to
    )

    let flags = fcntl(socketFD,F_GETFL)
    let _ = fcntl(socketFD,F_SETFL,flags | O_NONBLOCK)

    let sockKqueue = kqueue()
    if sockKqueue == -1 {
        print("Error creating kqueue")
      }
      var sockKevent = kevent(
        ident: UInt(socketFD),
        filter: Int16(EVFILT_READ),
        flags: UInt16(EV_ADD | EV_ENABLE),
        fflags: 0,
        data: 0,
        udata: nil)
      kevent(sockKqueue, &sockKevent, 1, nil, 0, nil)
      var event = kevent()
      if listenResult == -1 {
      print("Error setting our socket to listen")
      return
    }
    while (!ende!) {
      var addr = sockaddr()
      var addr_len :socklen_t = 0
      while (!ende!) {
          print("About to accept")
          let status = kevent(sockKqueue, nil, 0, &event, 1, nil)
          if  status == 0 {
            print("Timeout")
            continue
          } else if status > 0 {
              if (event.flags & UInt16(EV_EOF)) == EV_EOF {
                print("The socket (\(socketFD)) has been closed.")
                continue
              }
              print("File descriptor: \(socketFD) - has \(event.data) characters for reading")
            }
            else {
              print("Error reading kevent")
              continue
            }
          let accFD = accept(socketFD, &addr, &addr_len)
          if (accFD > 0){
              print("Accepted new client with file descriptor: \(accFD)")
              var val:UInt8 = 0
              repeat {
                  usleep(1)
                  OSMemoryBarrier()
                  val = bval!.pointee!.load(as:UInt8.self)
              }while ( val == 1 || val == 2)
              OSMemoryBarrier()
              bval!.pointee!.storeBytes(of:1,as: UInt8.self)
              repeat {
                  usleep(1)
                  OSMemoryBarrier()
                  val = bval!.pointee!.load(as:UInt8.self)
              }while ( val == 2)
              OSMemoryBarrier()
              bval!.pointee!.storeBytes(of:2,as: UInt8.self)
              accarrFD!.append(accFD)
              OSMemoryBarrier()
              bval!.pointee!.storeBytes(of:0,as:UInt8.self)
              if (semacnt! < factor) {
                let handle = Worker();
                handle.start()
              }
            } else {
                print("Error accepting connection")
            }
            OSMemoryBarrier() /// barrier needed here
        }
    }
    exit(EXIT_SUCCESS)
  }

}
BTW, jel provaljujete ovde da sam upravo izumeo svoj test and set lock free algoritam :P
 

Back
Top