Merge pull request #2 from danshevluk/development

Refactoring and Cocoapods support
This commit is contained in:
Dan 2016-11-05 10:36:44 +03:00 committed by Dan Shevlyuk
commit 5ea11facb0
10 changed files with 435 additions and 401 deletions

1
.swift-version Normal file
View File

@ -0,0 +1 @@
3.0

27
SwiftSocket.podspec Normal file
View File

@ -0,0 +1,27 @@
Pod::Spec.new do |s|
s.name = "SwiftSocket"
s.version = "1.1"
s.summary = "A cool framework to work with TCP and UDP sockets"
s.description = <<-DESC
SwiftSocket profieds an easy way to create TCP or UDP clients and servers 💁
DESC
s.homepage = "https://github.com/danshevluk/SwiftSocket"
s.license = { :type => "BSD" }
s.author = { "Dan Shevlyuk" => "danshevlyuk@icloud.com" }
s.social_media_url = "http://twitter.com/danshevluk"
s.ios.deployment_target = '8.0'
# s.osx.deployment_target = '10.7'
s.source = {
:git => 'https://github.com/danshevluk/SwiftSocket.git',
:tag => s.version
}
s.source_files = 'SwiftSocket/**/*'
s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3' }
end

View File

@ -7,24 +7,14 @@
objects = {
/* Begin PBXBuildFile section */
377DAA501DCDC29900009697 /* TCPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377DAA4F1DCDC29900009697 /* TCPClient.swift */; };
377DAA541DCDC2A900009697 /* UDPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377DAA511DCDC2A900009697 /* UDPClient.swift */; };
377DAA551DCDC2A900009697 /* ytcpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 377DAA521DCDC2A900009697 /* ytcpsocket.c */; };
377DAA561DCDC2A900009697 /* yudpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 377DAA531DCDC2A900009697 /* yudpsocket.c */; };
377DAA581DCDC2B400009697 /* Socket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377DAA571DCDC2B400009697 /* Socket.swift */; };
55A676E319A5FFCF00663380 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A676E019A5FFCF00663380 /* main.swift */; };
D430837D1A565F29004DE4D4 /* ysocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43083781A565EBF004DE4D4 /* ysocket.swift */; };
D430837E1A565F29004DE4D4 /* ytcpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = D43083791A565EBF004DE4D4 /* ytcpsocket.c */; };
D430837F1A565F29004DE4D4 /* ytcpsocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = D430837A1A565EBF004DE4D4 /* ytcpsocket.swift */; };
D43083801A565F29004DE4D4 /* yudpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = D430837B1A565EBF004DE4D4 /* yudpsocket.c */; };
D43083811A565F29004DE4D4 /* yudpsocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = D430837C1A565EBF004DE4D4 /* yudpsocket.swift */; };
D430838C1A565F7F004DE4D4 /* ysocket-ios.h in Headers */ = {isa = PBXBuildFile; fileRef = D430838B1A565F7F004DE4D4 /* ysocket-ios.h */; settings = {ATTRIBUTES = (Public, ); }; };
D43083A01A565F9F004DE4D4 /* ysocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43083781A565EBF004DE4D4 /* ysocket.swift */; };
D43083A11A565F9F004DE4D4 /* ytcpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = D43083791A565EBF004DE4D4 /* ytcpsocket.c */; };
D43083A21A565F9F004DE4D4 /* ytcpsocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = D430837A1A565EBF004DE4D4 /* ytcpsocket.swift */; };
D43083A31A565F9F004DE4D4 /* yudpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = D430837B1A565EBF004DE4D4 /* yudpsocket.c */; };
D43083A41A565F9F004DE4D4 /* yudpsocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = D430837C1A565EBF004DE4D4 /* yudpsocket.swift */; };
D4F0E40A1A5661260085C247 /* ysocketOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = D4F0E4091A5661260085C247 /* ysocketOSX.h */; settings = {ATTRIBUTES = (Public, ); }; };
D4F0E41E1A56613C0085C247 /* ysocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = D43083781A565EBF004DE4D4 /* ysocket.swift */; };
D4F0E41F1A56613C0085C247 /* ytcpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = D43083791A565EBF004DE4D4 /* ytcpsocket.c */; };
D4F0E4201A56613C0085C247 /* ytcpsocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = D430837A1A565EBF004DE4D4 /* ytcpsocket.swift */; };
D4F0E4211A56613C0085C247 /* yudpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = D430837B1A565EBF004DE4D4 /* yudpsocket.c */; };
D4F0E4221A56613C0085C247 /* yudpsocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = D430837C1A565EBF004DE4D4 /* yudpsocket.swift */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -40,13 +30,13 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
377DAA4F1DCDC29900009697 /* TCPClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TCPClient.swift; path = SwiftSocket/Source/TCPClient.swift; sourceTree = SOURCE_ROOT; };
377DAA511DCDC2A900009697 /* UDPClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = UDPClient.swift; path = SwiftSocket/Source/UDPClient.swift; sourceTree = SOURCE_ROOT; };
377DAA521DCDC2A900009697 /* ytcpsocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ytcpsocket.c; path = SwiftSocket/Source/ytcpsocket.c; sourceTree = SOURCE_ROOT; };
377DAA531DCDC2A900009697 /* yudpsocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = yudpsocket.c; path = SwiftSocket/Source/yudpsocket.c; sourceTree = SOURCE_ROOT; };
377DAA571DCDC2B400009697 /* Socket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Socket.swift; path = SwiftSocket/Source/Socket.swift; sourceTree = SOURCE_ROOT; };
5518C82F19A329100049DC22 /* SwiftSocket */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SwiftSocket; sourceTree = BUILT_PRODUCTS_DIR; };
55A676E019A5FFCF00663380 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = main.swift; path = SwiftSocket/main.swift; sourceTree = SOURCE_ROOT; };
D43083781A565EBF004DE4D4 /* ysocket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ysocket.swift; sourceTree = "<group>"; };
D43083791A565EBF004DE4D4 /* ytcpsocket.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ytcpsocket.c; sourceTree = "<group>"; };
D430837A1A565EBF004DE4D4 /* ytcpsocket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ytcpsocket.swift; sourceTree = "<group>"; };
D430837B1A565EBF004DE4D4 /* yudpsocket.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = yudpsocket.c; sourceTree = "<group>"; };
D430837C1A565EBF004DE4D4 /* yudpsocket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = yudpsocket.swift; sourceTree = "<group>"; };
D43083871A565F7F004DE4D4 /* ysocket.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ysocket.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D430838A1A565F7F004DE4D4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D430838B1A565F7F004DE4D4 /* ysocket-ios.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ysocket-ios.h"; sourceTree = "<group>"; };
@ -112,11 +102,11 @@
D43083771A565EBF004DE4D4 /* ysocket */ = {
isa = PBXGroup;
children = (
D43083781A565EBF004DE4D4 /* ysocket.swift */,
D43083791A565EBF004DE4D4 /* ytcpsocket.c */,
D430837A1A565EBF004DE4D4 /* ytcpsocket.swift */,
D430837B1A565EBF004DE4D4 /* yudpsocket.c */,
D430837C1A565EBF004DE4D4 /* yudpsocket.swift */,
377DAA571DCDC2B400009697 /* Socket.swift */,
377DAA4F1DCDC29900009697 /* TCPClient.swift */,
377DAA521DCDC2A900009697 /* ytcpsocket.c */,
377DAA511DCDC2A900009697 /* UDPClient.swift */,
377DAA531DCDC2A900009697 /* yudpsocket.c */,
);
name = ysocket;
path = SwiftSocket/ysocket;
@ -245,7 +235,7 @@
TargetAttributes = {
5518C82E19A329100049DC22 = {
CreatedOnToolsVersion = 6.0;
LastSwiftMigration = 0800;
LastSwiftMigration = 0810;
};
D43083861A565F7F004DE4D4 = {
CreatedOnToolsVersion = 6.1.1;
@ -296,11 +286,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D430837D1A565F29004DE4D4 /* ysocket.swift in Sources */,
D430837E1A565F29004DE4D4 /* ytcpsocket.c in Sources */,
D430837F1A565F29004DE4D4 /* ytcpsocket.swift in Sources */,
D43083801A565F29004DE4D4 /* yudpsocket.c in Sources */,
D43083811A565F29004DE4D4 /* yudpsocket.swift in Sources */,
377DAA541DCDC2A900009697 /* UDPClient.swift in Sources */,
377DAA561DCDC2A900009697 /* yudpsocket.c in Sources */,
377DAA581DCDC2B400009697 /* Socket.swift in Sources */,
377DAA501DCDC29900009697 /* TCPClient.swift in Sources */,
377DAA551DCDC2A900009697 /* ytcpsocket.c in Sources */,
55A676E319A5FFCF00663380 /* main.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -309,11 +299,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D43083A01A565F9F004DE4D4 /* ysocket.swift in Sources */,
D43083A11A565F9F004DE4D4 /* ytcpsocket.c in Sources */,
D43083A21A565F9F004DE4D4 /* ytcpsocket.swift in Sources */,
D43083A31A565F9F004DE4D4 /* yudpsocket.c in Sources */,
D43083A41A565F9F004DE4D4 /* yudpsocket.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -321,11 +306,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D4F0E41E1A56613C0085C247 /* ysocket.swift in Sources */,
D4F0E41F1A56613C0085C247 /* ytcpsocket.c in Sources */,
D4F0E4201A56613C0085C247 /* ytcpsocket.swift in Sources */,
D4F0E4211A56613C0085C247 /* yudpsocket.c in Sources */,
D4F0E4221A56613C0085C247 /* yudpsocket.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -29,16 +29,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import Foundation
open class YSocket{
var addr:String
var port:Int
var fd:Int32?
init(){
self.addr=""
self.port=0
}
public init(addr a:String,port p:Int){
self.addr=a
self.port=p
open class YSocket {
let address: String
let port: Int
var fd: Int32?
public init(address: String, port: Int) {
self.address = address
self.port = port
}
}

View File

@ -0,0 +1,176 @@
/*
Copyright (c) <2014>, skysent
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by skysent.
4. Neither the name of the skysent nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY skysent ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL skysent BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import Foundation
@_silgen_name("ytcpsocket_connect") func c_ytcpsocket_connect(_ host:UnsafePointer<Int8>,port:Int32,timeout:Int32) -> Int32
@_silgen_name("ytcpsocket_close") func c_ytcpsocket_close(_ fd:Int32) -> Int32
@_silgen_name("ytcpsocket_send") func c_ytcpsocket_send(_ fd:Int32,buff:UnsafePointer<UInt8>,len:Int32) -> Int32
@_silgen_name("ytcpsocket_pull") func c_ytcpsocket_pull(_ fd:Int32,buff:UnsafePointer<UInt8>,len:Int32,timeout:Int32) -> Int32
@_silgen_name("ytcpsocket_listen") func c_ytcpsocket_listen(_ address:UnsafePointer<Int8>,port:Int32)->Int32
@_silgen_name("ytcpsocket_accept") func c_ytcpsocket_accept(_ onsocketfd:Int32,ip:UnsafePointer<Int8>,port:UnsafePointer<Int32>) -> Int32
open class TCPClient: YSocket {
/*
* connect to server
* return success or fail with message
*/
open func connect(timeout: Int) -> (Bool, String) {
let rs: Int32 = c_ytcpsocket_connect(self.address, port: Int32(self.port), timeout: Int32(timeout))
if rs > 0 {
self.fd = rs
return (true,"connect success")
} else {
switch rs {
case -1:
return (false,"qeury server fail")
case -2:
return (false,"connection closed")
case -3:
return (false,"connect timeout")
default:
return (false,"unknow err.")
}
}
}
/*
* close socket
* return success or fail with message
*/
open func close() -> (Bool, String) {
guard let fd = self.fd else { return (false,"socket not open") }
c_ytcpsocket_close(fd)
self.fd = nil
return (true,"close success")
}
/*
* send data
* return success or fail with message
*/
open func send(data: [UInt8]) -> (Bool, String) {
guard let fd = self.fd else { return (false,"socket not open") }
let sendsize: Int32 = c_ytcpsocket_send(fd, buff: data, len: Int32(data.count))
if Int(sendsize) == data.count {
return (true,"send success")
} else {
return (false,"send error")
}
}
/*
* send string
* return success or fail with message
*/
open func send(string: String) -> (Bool, String) {
guard let fd = self.fd else { return (false,"socket not open") }
let sendsize = c_ytcpsocket_send(fd, buff: string, len: Int32(strlen(string)))
if sendsize == Int32(strlen(string)) {
return (true,"send success")
} else {
return (false,"send error")
}
}
/*
*
* send nsdata
*/
open func send(data: Data) -> (Bool, String) {
guard let fd = self.fd else { return (false,"socket not open") }
var buff = [UInt8](repeating: 0x0,count: data.count)
(data as NSData).getBytes(&buff, length: data.count)
let sendsize = c_ytcpsocket_send(fd, buff: buff, len: Int32(data.count))
if sendsize == Int32(data.count) {
return (true,"send success")
} else {
return (false,"send error")
}
}
/*
* read data with expect length
* return success or fail with message
*/
open func read(_ expectlen:Int, timeout:Int = -1)->[UInt8]?{
guard let fd:Int32 = self.fd else { return nil }
var buff = [UInt8](repeating: 0x0,count: expectlen)
let readLen = c_ytcpsocket_pull(fd, buff: &buff, len: Int32(expectlen), timeout: Int32(timeout))
if readLen <= 0 { return nil }
let rs = buff[0...Int(readLen-1)]
let data: [UInt8] = Array(rs)
return data
}
}
open class TCPServer: YSocket {
open func listen() -> (Bool, String) {
let fd = c_ytcpsocket_listen(self.address, port: Int32(self.port))
if fd > 0 {
self.fd = fd
return (true,"listen success")
} else {
return (false,"listen fail")
}
}
open func accept() -> TCPClient? {
guard let serferfd = self.fd else { return nil }
var buff: [Int8] = [Int8](repeating: 0x0,count: 16)
var port: Int32 = 0
let clientfd: Int32 = c_ytcpsocket_accept(serferfd, ip: &buff, port: &port)
guard clientfd >= 0 else { return nil }
guard let address = String(cString: buff, encoding: String.Encoding.utf8) else { return nil }
let client = TCPClient(address: address, port: Int(port))
client.fd = clientfd
return client
}
open func close() -> (Bool, String) {
guard let fd: Int32=self.fd else { return (false,"socket not open") }
c_ytcpsocket_close(fd)
self.fd = nil
return (true, "close success")
}
}

View File

@ -39,128 +39,139 @@ import Foundation
@_silgen_name("enable_broadcast") func c_enable_broadcast(_ fd:Int32)
open class UDPClient: YSocket {
public override init(addr a:String,port p:Int){
super.init()
let remoteipbuff:[Int8] = [Int8](repeating: 0x0,count: 16)
let ret=c_yudpsocket_get_server_ip(a, ip: remoteipbuff)
if ret==0{
if let ip=String(cString: remoteipbuff, encoding: String.Encoding.utf8){
self.addr=ip
self.port=p
let fd:Int32=c_yudpsocket_client()
if fd>0{
self.fd=fd
}
}
public override init(address: String, port: Int) {
let remoteipbuff: [Int8] = [Int8](repeating: 0x0,count: 16)
let ret = c_yudpsocket_get_server_ip(address, ip: remoteipbuff)
guard let ip = String(cString: remoteipbuff, encoding: String.Encoding.utf8), ret == 0 else {
super.init(address: "", port: 0) //TODO: change to init?
return
}
super.init(address: ip, port: port)
let fd: Int32 = c_yudpsocket_client()
if fd > 0 {
self.fd = fd
}
}
/*
* send data
* return success or fail with message
*/
open func send(data d:[UInt8])->(Bool,String){
if let fd:Int32=self.fd{
let sendsize:Int32=c_yudpsocket_sentto(fd, buff: d, len: Int32(d.count), ip: self.addr,port: Int32(self.port))
if Int(sendsize)==d.count{
return (true,"send success")
}else{
return (false,"send error")
open func send(data d: [UInt8]) -> (Bool,String) {
if let fd: Int32 = self.fd {
let sendsize: Int32 = c_yudpsocket_sentto(fd, buff: d, len: Int32(d.count), ip: self.address, port: Int32(self.port))
if Int(sendsize) == d.count {
return (true, "send success")
} else {
return (false, "send error")
}
}else{
return (false,"socket not open")
} else {
return (false, "socket not open")
}
}
/*
* send string
* return success or fail with message
*/
open func send(str s:String)->(Bool,String){
if let fd:Int32=self.fd{
let sendsize:Int32=c_yudpsocket_sentto(fd, buff: s, len: Int32(strlen(s)), ip: self.addr,port: Int32(self.port))
if sendsize==Int32(strlen(s)){
open func send(str s:String) -> (Bool,String) {
if let fd: Int32 = self.fd {
let sendsize: Int32 = c_yudpsocket_sentto(fd, buff: s, len: Int32(strlen(s)), ip: self.address,port: Int32(self.port))
if sendsize == Int32(strlen(s)) {
return (true,"send success")
}else{
} else {
return (false,"send error")
}
}else{
} else {
return (false,"socket not open")
}
}
/*
* enableBroadcast
*/
open func enableBroadcast(){
if let fd:Int32=self.fd{
open func enableBroadcast() {
if let fd: Int32 = self.fd {
c_enable_broadcast(fd)
}
}
/*
*
* send nsdata
*/
open func send(data d:Data)->(Bool,String){
if let fd:Int32=self.fd{
open func send(data d:Data) -> (Bool,String) {
if let fd: Int32 = self.fd {
var buff:[UInt8] = [UInt8](repeating: 0x0,count: d.count)
(d as NSData).getBytes(&buff, length: d.count)
let sendsize:Int32=c_yudpsocket_sentto(fd, buff: buff, len: Int32(d.count), ip: self.addr,port: Int32(self.port))
let sendsize:Int32=c_yudpsocket_sentto(fd, buff: buff, len: Int32(d.count), ip: self.address,port: Int32(self.port))
if sendsize==Int32(d.count){
return (true,"send success")
}else{
} else {
return (false,"send error")
}
}else{
} else {
return (false,"socket not open")
}
}
open func close()->(Bool,String){
if let fd:Int32=self.fd{
open func close() -> (Bool,String) {
if let fd = self.fd{
c_yudpsocket_close(fd)
self.fd=nil
return (true,"close success")
}else{
} else {
return (false,"socket not open")
}
}
//TODO add multycast and boardcast
}
open class UDPServer:YSocket{
public override init(addr a:String,port p:Int){
super.init(addr: a, port: p)
let fd:Int32 = c_yudpsocket_server(self.addr, port: Int32(self.port))
if fd>0{
self.fd=fd
open class UDPServer: YSocket{
public override init(address: String, port: Int) {
super.init(address: address, port: port)
let fd: Int32 = c_yudpsocket_server(self.address, port: Int32(self.port))
if fd > 0 {
self.fd = fd
}
}
//TODO add multycast and boardcast
open func recv(_ expectlen:Int)->([UInt8]?,String,Int){
if let fd:Int32 = self.fd{
var buff:[UInt8] = [UInt8](repeating: 0x0,count: expectlen)
var remoteipbuff:[Int8] = [Int8](repeating: 0x0,count: 16)
var remoteport:Int32=0
let readLen:Int32=c_yudpsocket_recive(fd, buff: buff, len: Int32(expectlen), ip: &remoteipbuff, port: &remoteport)
let port:Int=Int(remoteport)
var addr:String=""
if let ip=String(cString: remoteipbuff, encoding: String.Encoding.utf8){
addr=ip
open func recv(_ expectlen: Int) -> ([UInt8]?, String, Int) {
if let fd = self.fd {
var buff: [UInt8] = [UInt8](repeating: 0x0,count: expectlen)
var remoteipbuff: [Int8] = [Int8](repeating: 0x0,count: 16)
var remoteport: Int32 = 0
let readLen: Int32 = c_yudpsocket_recive(fd, buff: buff, len: Int32(expectlen), ip: &remoteipbuff, port: &remoteport)
let port: Int = Int(remoteport)
var address = ""
if let ip = String(cString: remoteipbuff, encoding: String.Encoding.utf8) {
address = ip
}
if readLen<=0{
return (nil,addr,port)
if readLen <= 0 {
return (nil, address, port)
}
let rs=buff[0...Int(readLen-1)]
let data:[UInt8] = Array(rs)
return (data,addr,port)
let rs = buff[0...Int(readLen-1)]
let data: [UInt8] = Array(rs)
return (data, address, port)
}
return (nil,"no ip",0)
}
open func close()->(Bool,String){
if let fd:Int32=self.fd{
open func close() -> (Bool, String) {
if let fd = self.fd {
c_yudpsocket_close(fd)
self.fd=nil
return (true,"close success")
}else{
return (false,"socket not open")
self.fd = nil
return (true, "close success")
} else {
return (false, "socket not open")
}
}
}

View File

@ -42,122 +42,133 @@
#include <fcntl.h>
#include <signal.h>
#include <sys/select.h>
void ytcpsocket_set_block(int socket,int on) {
void ytcpsocket_set_block(int socket, int on) {
int flags;
flags = fcntl(socket,F_GETFL,0);
if (on==0) {
flags = fcntl(socket, F_GETFL, 0);
if (on == 0) {
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
}else{
} else {
flags &= ~ O_NONBLOCK;
fcntl(socket, F_SETFL, flags);
}
}
int ytcpsocket_connect(const char *host,int port,int timeout){
int ytcpsocket_connect(const char *host, int port, int timeout) {
struct sockaddr_in sa;
struct hostent *hp;
int sockfd = -1;
hp = gethostbyname(host);
if(hp==NULL){
if (hp == NULL) {
return -1;
}
bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
sa.sin_port = htons(port);
sockfd = socket(hp->h_addrtype, SOCK_STREAM, 0);
ytcpsocket_set_block(sockfd,0);
connect(sockfd, (struct sockaddr *)&sa, sizeof(sa));
fd_set fdwrite;
fd_set fdwrite;
struct timeval tvSelect;
FD_ZERO(&fdwrite);
FD_SET(sockfd, &fdwrite);
tvSelect.tv_sec = timeout;
tvSelect.tv_usec = 0;
int retval = select(sockfd + 1,NULL, &fdwrite, NULL, &tvSelect);
if (retval<0) {
int retval = select(sockfd + 1, NULL, &fdwrite, NULL, &tvSelect);
if (retval < 0) {
close(sockfd);
return -2;
}else if(retval==0){//timeout
} else if(retval == 0) {//timeout
close(sockfd);
return -3;
}else{
int error=0;
int errlen=sizeof(error);
} else {
int error = 0;
int errlen = sizeof(error);
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&errlen);
if(error!=0){
if (error != 0) {
close(sockfd);
return -4;//connect fail
}
ytcpsocket_set_block(sockfd, 1);
int set = 1;
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
return sockfd;
}
}
int ytcpsocket_close(int socketfd){
return close(socketfd);
}
int ytcpsocket_pull(int socketfd,char *data,int len,int timeout_sec){
if (timeout_sec>0) {
int ytcpsocket_pull(int socketfd, char *data, int len, int timeout_sec) {
if (timeout_sec > 0) {
fd_set fdset;
struct timeval timeout;
timeout.tv_usec = 0;
timeout.tv_sec = timeout_sec;
FD_ZERO(&fdset);
FD_SET(socketfd, &fdset);
int ret = select(socketfd+1, &fdset, NULL, NULL, &timeout);
if (ret<=0) {
int ret = select(socketfd + 1, &fdset, NULL, NULL, &timeout);
if (ret <= 0) {
return ret; // select-call failed or timeout occurred (before anything was sent)
}
}
int readlen=(int)read(socketfd,data,len);
int readlen = (int)read(socketfd, data, len);
return readlen;
}
int ytcpsocket_send(int socketfd,const char *data,int len){
int byteswrite=0;
while (len-byteswrite>0) {
int writelen=(int)write(socketfd, data+byteswrite, len-byteswrite);
if (writelen<0) {
int ytcpsocket_send(int socketfd, const char *data, int len){
int byteswrite = 0;
while (len - byteswrite > 0) {
int writelen = (int)write(socketfd, data + byteswrite, len - byteswrite);
if (writelen < 0) {
return -1;
}
byteswrite+=writelen;
byteswrite += writelen;
}
return byteswrite;
}
//return socket fd
int ytcpsocket_listen(const char *addr,int port){
int ytcpsocket_listen(const char *address, int port) {
//create socket
int socketfd=socket(AF_INET, SOCK_STREAM, 0);
int reuseon = 1;
setsockopt( socketfd, SOL_SOCKET, SO_REUSEADDR, &reuseon, sizeof(reuseon) );
int socketfd = socket(AF_INET, SOCK_STREAM, 0);
int reuseon = 1;
setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &reuseon, sizeof(reuseon));
//bind
struct sockaddr_in serv_addr;
memset( &serv_addr, '\0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(addr);
serv_addr.sin_addr.s_addr = inet_addr(address);
serv_addr.sin_port = htons(port);
int r=bind(socketfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if(r==0){
if (listen(socketfd, 128)==0) {
int r = bind(socketfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (r == 0) {
if (listen(socketfd, 128) == 0) {
return socketfd;
}else{
} else {
return -2;//listen error
}
}else{
} else {
return -1;//bind error
}
}
//return client socket fd
int ytcpsocket_accept(int onsocketfd,char *remoteip,int* remoteport){
int ytcpsocket_accept(int onsocketfd, char *remoteip, int *remoteport) {
socklen_t clilen;
struct sockaddr_in cli_addr;
clilen = sizeof(cli_addr);
int newsockfd = accept(onsocketfd, (struct sockaddr *) &cli_addr, &clilen);
char *clientip=inet_ntoa(cli_addr.sin_addr);
memcpy(remoteip, clientip, strlen(clientip));
*remoteport=cli_addr.sin_port;
if(newsockfd>0){
*remoteport = cli_addr.sin_port;
if (newsockfd > 0) {
return newsockfd;
}else{
} else {
return -1;
}
}

View File

@ -39,84 +39,97 @@
#define yudpsocket_buff_len 8192
//return socket fd
int yudpsocket_server(const char *addr,int port){
int yudpsocket_server(const char *address, int port) {
//create socket
int socketfd=socket(AF_INET, SOCK_DGRAM, 0);
int reuseon = 1;
int reuseon = 1;
int r = -1;
//bind
struct sockaddr_in serv_addr;
serv_addr.sin_len = sizeof(struct sockaddr_in);
serv_addr.sin_len = sizeof(struct sockaddr_in);
serv_addr.sin_family = AF_INET;
if(addr == NULL || strlen(addr) == 0 || strcmp(addr, "255.255.255.255") == 0)
{
r = setsockopt( socketfd, SOL_SOCKET, SO_BROADCAST, &reuseon, sizeof(reuseon) );
serv_addr.sin_port = htons(port);
if (address == NULL || strlen(address) == 0 || strcmp(address, "255.255.255.255") == 0) {
r = setsockopt(socketfd, SOL_SOCKET, SO_BROADCAST, &reuseon, sizeof(reuseon));
serv_addr.sin_port = htons(port);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
}else{
r = setsockopt( socketfd, SOL_SOCKET, SO_REUSEADDR, &reuseon, sizeof(reuseon) );
serv_addr.sin_addr.s_addr = inet_addr(addr);
} else {
r = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &reuseon, sizeof(reuseon));
serv_addr.sin_addr.s_addr = inet_addr(address);
serv_addr.sin_port = htons(port);
memset( &serv_addr, '\0', sizeof(serv_addr));
}
if(r==-1){
if (r == -1) {
return -1;
}
r=bind(socketfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if(r==0){
r = bind(socketfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
if (r == 0) {
return socketfd;
}else{
} else {
return -1;
}
}
int yudpsocket_recive(int socket_fd,char *outdata,int expted_len,char *remoteip,int* remoteport){
struct sockaddr_in cli_addr;
socklen_t clilen=sizeof(cli_addr);
int yudpsocket_recive(int socket_fd, char *outdata, int expted_len, char *remoteip, int *remoteport) {
struct sockaddr_in cli_addr;
socklen_t clilen = sizeof(cli_addr);
memset(&cli_addr, 0x0, sizeof(struct sockaddr_in));
int len=(int)recvfrom(socket_fd, outdata, expted_len, 0, (struct sockaddr *)&cli_addr, &clilen);
char *clientip=inet_ntoa(cli_addr.sin_addr);
int len = (int)recvfrom(socket_fd, outdata, expted_len, 0, (struct sockaddr *)&cli_addr, &clilen);
char *clientip = inet_ntoa(cli_addr.sin_addr);
memcpy(remoteip, clientip, strlen(clientip));
*remoteport=cli_addr.sin_port;
*remoteport = cli_addr.sin_port;
return len;
}
int yudpsocket_close(int socket_fd){
int yudpsocket_close(int socket_fd) {
return close(socket_fd);
}
//return socket fd
int yudpsocket_client(){
int yudpsocket_client() {
//create socket
int socketfd=socket(AF_INET, SOCK_DGRAM, 0);
int reuseon = 1;
setsockopt( socketfd, SOL_SOCKET, SO_REUSEADDR, &reuseon, sizeof(reuseon) );
int socketfd = socket(AF_INET, SOCK_DGRAM, 0);
int reuseon = 1;
setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &reuseon, sizeof(reuseon));
return socketfd;
}
//enable broadcast
void enable_broadcast(int socket_fd){
int reuseon = 1;
setsockopt( socket_fd, SOL_SOCKET, SO_BROADCAST, &reuseon, sizeof(reuseon) );
void enable_broadcast(int socket_fd) {
int reuseon = 1;
setsockopt(socket_fd, SOL_SOCKET, SO_BROADCAST, &reuseon, sizeof(reuseon));
}
int yudpsocket_get_server_ip(char *host,char *ip){
int yudpsocket_get_server_ip(char *host, char *ip) {
struct hostent *hp;
struct sockaddr_in addr;
struct sockaddr_in address;
hp = gethostbyname(host);
if(hp==NULL){
if (hp == NULL) {
return -1;
}
bcopy((char *)hp->h_addr, (char *)&addr.sin_addr, hp->h_length);
char *clientip=inet_ntoa(addr.sin_addr);
bcopy((char *)hp->h_addr, (char *)&address.sin_addr, hp->h_length);
char *clientip = inet_ntoa(address.sin_addr);
memcpy(ip, clientip, strlen(clientip));
return 0;
}
//send message to addr and port
int yudpsocket_sentto(int socket_fd,char *msg,int len, char *toaddr, int topotr){
struct sockaddr_in addr;
socklen_t addrlen=sizeof(addr);
memset(&addr, 0x0, sizeof(struct sockaddr_in));
addr.sin_family=AF_INET;
addr.sin_port=htons(topotr);
addr.sin_addr.s_addr=inet_addr(toaddr);
int sendlen=(int)sendto(socket_fd, msg, len, 0, (struct sockaddr *)&addr, addrlen);
//send message to address and port
int yudpsocket_sentto(int socket_fd, char *msg, int len, char *toaddr, int topotr) {
struct sockaddr_in address;
socklen_t addrlen = sizeof(address);
memset(&address, 0x0, sizeof(struct sockaddr_in));
address.sin_family = AF_INET;
address.sin_port = htons(topotr);
address.sin_addr.s_addr = inet_addr(toaddr);
int sendlen = (int)sendto(socket_fd, msg, len, 0, (struct sockaddr *)&address, addrlen);
return sendlen;
}

View File

@ -31,12 +31,12 @@ import Foundation
import Darwin.C
func testtcpclient(){
//socket
let client:TCPClient = TCPClient(addr: "ixy.io", port: 80)
let client:TCPClient = TCPClient(address: "ixy.io", port: 80)
//
var (success,errmsg)=client.connect(timeout: 1)
if success{
//
var (success,errmsg)=client.send(str:"GET / HTTP/1.0\n\n" )
var (success,errmsg)=client.send(string: "GET / HTTP/1.0\n\n")
if success{
//
let data=client.read(1024*10)
@ -53,13 +53,13 @@ func testtcpclient(){
}
}
func echoService(client c:TCPClient){
print("newclient from:\(c.addr)[\(c.port)]")
print("newclient from:\(c.address)[\(c.port)]")
let d=c.read(1024*10)
c.send(data: d!)
c.close()
}
func testtcpserver(){
let server:TCPServer = TCPServer(addr: "127.0.0.1", port: 8080)
let server:TCPServer = TCPServer(address: "127.0.0.1", port: 8080)
var (success,msg)=server.listen()
if success{
while true{
@ -74,10 +74,10 @@ func testtcpserver(){
}
}
//testclient()
func testudpserver(){
func testudpserver() {
DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.background).async(execute: { () -> Void in
let server:UDPServer=UDPServer(addr:"127.0.0.1",port:8080)
let run:Bool=true
let server: UDPServer = UDPServer(address:"127.0.0.1",port:8080)
let run = true
while run{
var (data,remoteip,remoteport)=server.recv(1024)
print("recive")
@ -93,7 +93,7 @@ func testudpserver(){
})
}
func testudpclient(){
let client:UDPClient=UDPClient(addr: "localhost", port: 8080)
let client = UDPClient(address: "localhost", port: 8080)
print("send hello world")
client.send(str: "hello world")
client.close()
@ -102,14 +102,14 @@ func testudpclient(){
func testudpBroadcastserver(){
DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.background).async(execute: { () -> Void in
//turn the server to broadcast mode with the address 255.255.255.255 or empty string
let server:UDPServer=UDPServer(addr:"",port:8080)
let run:Bool=true
let server = UDPServer(address:"",port:8080)
let run = true
print("server.started")
while run{
let (data,remoteip,remoteport)=server.recv(1024)
while run {
let (data,remoteip,remoteport) = server.recv(1024)
print("recive\(remoteip);\(remoteport)")
if let d=data{
if let str=String(bytes: d, encoding: String.Encoding.utf8){
if let data = data {
if let str = String(bytes: data, encoding: String.Encoding.utf8) {
print(str)
}
}
@ -123,7 +123,7 @@ func testudpBroadcastclient(){
//wait a few second till server will ready
sleep(2)
print("Broadcastclient.send...")
let clientB:UDPClient = UDPClient(addr: "255.255.255.255", port: 8080)
let clientB = UDPClient(address: "255.255.255.255", port: 8080)
clientB.enableBroadcast()
clientB.send(str: "test hello from broadcast")
clientB.close()

View File

@ -1,185 +0,0 @@
/*
Copyright (c) <2014>, skysent
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by skysent.
4. Neither the name of the skysent nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY skysent ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL skysent BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import Foundation
@_silgen_name("ytcpsocket_connect") func c_ytcpsocket_connect(_ host:UnsafePointer<Int8>,port:Int32,timeout:Int32) -> Int32
@_silgen_name("ytcpsocket_close") func c_ytcpsocket_close(_ fd:Int32) -> Int32
@_silgen_name("ytcpsocket_send") func c_ytcpsocket_send(_ fd:Int32,buff:UnsafePointer<UInt8>,len:Int32) -> Int32
@_silgen_name("ytcpsocket_pull") func c_ytcpsocket_pull(_ fd:Int32,buff:UnsafePointer<UInt8>,len:Int32,timeout:Int32) -> Int32
@_silgen_name("ytcpsocket_listen") func c_ytcpsocket_listen(_ addr:UnsafePointer<Int8>,port:Int32)->Int32
@_silgen_name("ytcpsocket_accept") func c_ytcpsocket_accept(_ onsocketfd:Int32,ip:UnsafePointer<Int8>,port:UnsafePointer<Int32>) -> Int32
open class TCPClient:YSocket{
/*
* connect to server
* return success or fail with message
*/
open func connect(timeout t:Int)->(Bool,String){
let rs:Int32=c_ytcpsocket_connect(self.addr, port: Int32(self.port), timeout: Int32(t))
if rs>0{
self.fd=rs
return (true,"connect success")
}else{
switch rs{
case -1:
return (false,"qeury server fail")
case -2:
return (false,"connection closed")
case -3:
return (false,"connect timeout")
default:
return (false,"unknow err.")
}
}
}
/*
* close socket
* return success or fail with message
*/
open func close()->(Bool,String){
if let fd:Int32=self.fd{
c_ytcpsocket_close(fd)
self.fd=nil
return (true,"close success")
}else{
return (false,"socket not open")
}
}
/*
* send data
* return success or fail with message
*/
open func send(data d:[UInt8])->(Bool,String){
if let fd:Int32=self.fd{
let sendsize:Int32=c_ytcpsocket_send(fd, buff: d, len: Int32(d.count))
if Int(sendsize)==d.count{
return (true,"send success")
}else{
return (false,"send error")
}
}else{
return (false,"socket not open")
}
}
/*
* send string
* return success or fail with message
*/
open func send(str s:String)->(Bool,String){
if let fd:Int32=self.fd{
let sendsize:Int32=c_ytcpsocket_send(fd, buff: s, len: Int32(strlen(s)))
if sendsize==Int32(strlen(s)){
return (true,"send success")
}else{
return (false,"send error")
}
}else{
return (false,"socket not open")
}
}
/*
*
* send nsdata
*/
open func send(data d:Data)->(Bool,String){
if let fd:Int32=self.fd{
var buff:[UInt8] = [UInt8](repeating: 0x0,count: d.count)
(d as NSData).getBytes(&buff, length: d.count)
let sendsize:Int32=c_ytcpsocket_send(fd, buff: buff, len: Int32(d.count))
if sendsize==Int32(d.count){
return (true,"send success")
}else{
return (false,"send error")
}
}else{
return (false,"socket not open")
}
}
/*
* read data with expect length
* return success or fail with message
*/
open func read(_ expectlen:Int, timeout:Int = -1)->[UInt8]?{
if let fd:Int32 = self.fd{
var buff:[UInt8] = [UInt8](repeating: 0x0,count: expectlen)
let readLen:Int32=c_ytcpsocket_pull(fd, buff: &buff, len: Int32(expectlen), timeout: Int32(timeout))
if readLen<=0{
return nil
}
let rs=buff[0...Int(readLen-1)]
let data:[UInt8] = Array(rs)
return data
}
return nil
}
}
open class TCPServer:YSocket{
open func listen()->(Bool,String){
let fd:Int32=c_ytcpsocket_listen(self.addr, port: Int32(self.port))
if fd>0{
self.fd=fd
return (true,"listen success")
}else{
return (false,"listen fail")
}
}
open func accept()->TCPClient?{
if let serferfd=self.fd{
var buff:[Int8] = [Int8](repeating: 0x0,count: 16)
var port:Int32=0
let clientfd:Int32=c_ytcpsocket_accept(serferfd, ip: &buff,port: &port)
if clientfd<0{
return nil
}
let tcpClient:TCPClient=TCPClient()
tcpClient.fd=clientfd
tcpClient.port=Int(port)
if let addr=String(cString: buff, encoding: String.Encoding.utf8){
tcpClient.addr=addr
}
return tcpClient
}
return nil
}
open func close()->(Bool,String){
if let fd:Int32=self.fd{
c_ytcpsocket_close(fd)
self.fd=nil
return (true,"close success")
}else{
return (false,"socket not open")
}
}
}