我想用苹果新语言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
}
}
答案 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()
它非常快,很有乐趣