Swift tcp多线程服务器

时间:2014-08-25 21:50:06

标签: multithreading tcp swift

我想用苹果新语言Swift构建一个多线程tcp服务器。 现在我有两个问题。

1。)我的程序打开一个端口,我可以用telnet连接。但我无法在客户端和服务器之间发送数据

2.。)如何将NSConnection放入NSRunLoop或我如何找到NSRunLoop进行交互?

import Foundation

class AntSchlumpf:NSObject , NSConnectionDelegate{

    func createConversationForConnection(conn: NSConnection!) -> AnyObject!{
        var any = []
        println("Geht delegater")
        return any

    }
    func connection(parentConnection: NSConnection,shouldMakeNewConnection newConnnection: NSConnection) -> Bool
    {
        newConnnection.runInNewThread()
        newConnnection.removeRunLoop(NSRunLoop.currentRunLoop())
        println("Geht")
        return true
    }

}

class AntServer:NSConnection{

    let id : NSNumber?
    let port : UInt16?
    var serverSock : NSSocketPort?

    init(port:UInt16!, id:NSNumber?, host: String?){
        self.id = id
        self.port = port
        serverSock = NSSocketPort(TCPPort: port!)
        var fd = serverSock?.socket
        println(fd)

        super.init(receivePort: serverSock, sendPort: nil)
        self.independentConversationQueueing = true
        NSNotificationCenter.defaultCenter().addObserver(self, selector:"clientHasConnected:" , name: NSConnectionDidInitializeNotification, object: nil)
        self.delegate = AntSchlumpf()
        if(self.multipleThreadsEnabled){
            println("Multithread enabled")
        }

}
func clientHasConnected(notification: NSNotification){
    println("Observer gestartet")
}

func startServer(){
    println("Starting Server...")
    if(self.serverSock){
        println("Port connected at \(self.port)")
        self.rootObject = self
        NSNotificationCenter.defaultCenter().addObserver(self, selector:"clientHasConnected:" , name: NSConnectionDidInitializeNotification, object: nil)

    }

}
func createConversationForConnection(conn: NSConnection!) -> AnyObject!{
    var any = []
    println("Geht")
    return any

}
}

1 个答案:

答案 0 :(得分:0)

这是一个例子:

//
//  main.swift
//  NetServer
//   
//  Created by denis kohl on 11/26/14.
//  Copyright (c) 2014 denis kohl. All rights reserved.
//

import Foundation

class Connection : NSObject{
 var handle =  NSSocketNativeHandle()
var addressData = NSData()
init(handle: NSSocketNativeHandle, addressData: NSData){
    self.addressData = addressData
    self.handle = handle
 }
}



 class NetServer : NSObject {


 dynamic func runner(client: Connection){

    var buffer : UnsafeMutablePointer<Void> = UnsafeMutablePointer<Void>.alloc(1)
    while(keepRunning){
        var line = read(client.handle, buffer, 1024)
        var pData : NSData = NSData(bytes: UnsafePointer<UInt8>(buffer),length: line)
        println(pData)
        var pStr : NSString = NSString(bytes: UnsafePointer<UInt8>(buffer), length: line , encoding: NSUTF8StringEncoding)!
        //var nStr : NSString = NSString(bytesNoCopy: UnsafePointer<UInt8>(buffer), length: line, encoding: NSUTF8StringEncoding, freeWhenDone: true)!
        var res : String = pStr;
        println(pStr);
        write(client.handle, res, UInt(res.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)))
        buffer.destroy()
        //localBuffer.destroy()

    }

}

var buffer : UnsafeMutablePointer<Void> = UnsafeMutablePointer<Void>.alloc(1)
var res : String = "Willkommen";
var ip : String
var port : UInt16
var keepRunning = true
var clientIndex : Int = 0


init(ip:String, port:UInt16){
    self.ip = ip
    self.port = port
}





private func socket_native_handle_create_ipv4() -> NSSocketNativeHandle {
    return socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
}



private func socket_native_handle_create_ipv6() -> NSSocketNativeHandle {
    return socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP)
}



private func socket_native_handle_bind(handle: NSSocketNativeHandle, addressData: NSData, error: NSErrorPointer) -> Bool {

    if bind(handle, UnsafePointer<sockaddr>(addressData.bytes), socklen_t(addressData.length)) != 0 {

    if error != nil {

         let reason  = NSString(CString: strerror(errno), encoding: NSASCIIStringEncoding)!

                error.memory = NSError(domain: "SocksErrorDomain", code: Int(errno), userInfo: [NSLocalizedFailureReasonErrorKey: reason])
        }

        return false

    }

    return true

}



private func socket_native_handle_listen(handle: NSSocketNativeHandle, backlog: UInt, error: NSErrorPointer) -> Bool {

    if listen(handle, Int32(backlog)) != 0 {

        if error != nil {

            let reason : NSString = NSString(CString: strerror(errno), encoding: NSASCIIStringEncoding)!

                error.memory = NSError(domain: "SocksErrorDomain", code: Int(errno), userInfo: [NSLocalizedFailureReasonErrorKey: reason])



        }

        return false

    }

    return true

}



private func socket_native_handle_connect(handle: NSSocketNativeHandle, addressData: NSData, error: NSErrorPointer) -> Bool {

    if connect(handle, UnsafePointer<sockaddr>(addressData.bytes), socklen_t(addressData.length)) != 0 {

        if error != nil {

            let reason : NSString = NSString(CString: strerror(errno), encoding: NSASCIIStringEncoding)!

                error.memory = NSError(domain: "SocksErrorDomain", code: Int(errno), userInfo: [NSLocalizedFailureReasonErrorKey: reason])

        }

        return false

    }

    return true

}



private func socket_native_handle_accept(handle: NSSocketNativeHandle, error: NSErrorPointer) -> (handle: NSSocketNativeHandle, addressData: NSData)? {

    let addressData = NSMutableData(length: max(sizeof(sockaddr_in), sizeof(sockaddr_in6)))!

    var addressLength = socklen_t(addressData.length)

    let accepted = accept(handle, UnsafeMutablePointer<sockaddr>(addressData.mutableBytes), &addressLength)

    if accepted < 0 {

        if error != nil {

            let reason : NSString = NSString(CString: strerror(errno), encoding: NSASCIIStringEncoding)!

                error.memory = NSError(domain: "SocksErrorDomain", code: Int(errno), userInfo: [NSLocalizedFailureReasonErrorKey: reason])
        }

        return nil
    }

    return (handle: accepted, addressData: addressData.subdataWithRange(NSMakeRange(0, Int(addressLength))))

}


private func socket_native_handle_accept_connect(handle: NSSocketNativeHandle, error: NSErrorPointer) -> Connection? {

    let addressData = NSMutableData(length: max(sizeof(sockaddr_in), sizeof(sockaddr_in6)))!


    var addressLength = socklen_t(addressData.length)

    let accepted = accept(handle, UnsafeMutablePointer<sockaddr>(addressData.mutableBytes), &addressLength)

    if accepted < 0 {

        if error != nil {

            let reason : NSString = NSString(CString: strerror(errno), encoding: NSASCIIStringEncoding)!

            error.memory = NSError(domain: "SocksErrorDomain", code: Int(errno), userInfo: [NSLocalizedFailureReasonErrorKey: reason])
        }

        return nil
    }
    var myConnection  : Connection = Connection(handle: accepted, addressData: addressData.subdataWithRange(NSMakeRange(0, Int(addressLength))))
    return myConnection

}




private func socket_native_handle_close(handle: NSSocketNativeHandle) {

    close(handle)

}



private func sockaddr_create_ipv4(ip: String, port: UInt16) -> NSData? {

    let len = sizeof(sockaddr_in)

    let data = NSMutableData(length: len)!

    var addr = UnsafeMutablePointer<sockaddr_in>(data.mutableBytes)

    addr.memory.sin_len = __uint8_t(len)

    addr.memory.sin_family = sa_family_t(AF_INET)

    addr.memory.sin_port = _OSSwapInt16(__uint16_t(port))

    if inet_pton(Int32(AF_INET), (ip as NSString).UTF8String, &addr.memory.sin_addr) != 1 {

        return nil

    }

    return data

}



private func sockaddr_create_ipv6(ip: String, port: UInt) -> NSData? {

    let len = sizeof(sockaddr_in6)

    let data = NSMutableData(length: len)!

    var addr = UnsafeMutablePointer<sockaddr_in6>(data.mutableBytes)

    addr.memory.sin6_len = __uint8_t(len)

    addr.memory.sin6_family = sa_family_t(AF_INET6)

    addr.memory.sin6_port = _OSSwapInt16(__uint16_t(port))

    if inet_pton(Int32(AF_INET6), (ip as NSString).UTF8String, &addr.memory.sin6_addr) != 1 {

        return nil

    }

    return data

}




func main(){
    var error : NSErrorPointer = NSErrorPointer()

    let addr : NSData? = self.sockaddr_create_ipv4(self.ip,port: self.port)

    let handel : NSSocketNativeHandle = self.socket_native_handle_create_ipv4()
    if self.socket_native_handle_bind(handel, addressData: addr!, error: error)  == false {
        println("Can't bind to Port")
    }

    if self.socket_native_handle_listen(handel, backlog: 5, error: error) == false{
        println("Can't listen")
    }
    while(true){
        var c : Connection  = self.socket_native_handle_accept_connect(handel, error: error)!
        write(c.handle, res, UInt(res.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)))
        var temp  = UInt32(c.handle)
        println("Try to thread")
        var thread : NSThread =  NSThread(target:self, selector:Selector("runner:"), object:c )

        thread.start()
        println("Wait")
    }
}
}


var server  = NetServer(ip: "127.0.0.1", port: 6667)
server.main()

它非常快,很有乐趣