mirror of
https://github.com/jeremysrand/ListenerApp.git
synced 2025-02-21 01:28:57 +00:00
Add SwiftSocket to the project. I fought with cocoapods for a while but opted to just directly include the code because I was tired of fighting.
This commit is contained in:
parent
b7c020be62
commit
be95708466
@ -15,6 +15,12 @@
|
||||
9D51561026A1EF7C0075EBC7 /* ListenerAppUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D51560F26A1EF7C0075EBC7 /* ListenerAppUITests.swift */; };
|
||||
9D51562226A1F0DF0075EBC7 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 9D51562126A1F0DF0075EBC7 /* LICENSE */; };
|
||||
9D51563126A278BB0075EBC7 /* Speech.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D51563026A278BB0075EBC7 /* Speech.framework */; };
|
||||
9D51565226A36B410075EBC7 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D51564C26A36B410075EBC7 /* Result.swift */; };
|
||||
9D51565326A36B410075EBC7 /* yudpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D51564D26A36B410075EBC7 /* yudpsocket.c */; };
|
||||
9D51565426A36B410075EBC7 /* ytcpsocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 9D51564E26A36B410075EBC7 /* ytcpsocket.c */; };
|
||||
9D51565526A36B410075EBC7 /* UDPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D51564F26A36B410075EBC7 /* UDPClient.swift */; };
|
||||
9D51565626A36B410075EBC7 /* Socket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D51565026A36B410075EBC7 /* Socket.swift */; };
|
||||
9D51565726A36B410075EBC7 /* TCPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D51565126A36B410075EBC7 /* TCPClient.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -50,6 +56,14 @@
|
||||
9D51562126A1F0DF0075EBC7 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
|
||||
9D51562A26A1F1B40075EBC7 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
||||
9D51563026A278BB0075EBC7 /* Speech.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Speech.framework; path = System/Library/Frameworks/Speech.framework; sourceTree = SDKROOT; };
|
||||
9D51563726A36AF20075EBC7 /* ListenerApp-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ListenerApp-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
9D51564B26A36B410075EBC7 /* SwiftSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SwiftSocket.h; sourceTree = "<group>"; };
|
||||
9D51564C26A36B410075EBC7 /* Result.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Result.swift; sourceTree = "<group>"; };
|
||||
9D51564D26A36B410075EBC7 /* yudpsocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yudpsocket.c; sourceTree = "<group>"; };
|
||||
9D51564E26A36B410075EBC7 /* ytcpsocket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ytcpsocket.c; sourceTree = "<group>"; };
|
||||
9D51564F26A36B410075EBC7 /* UDPClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UDPClient.swift; sourceTree = "<group>"; };
|
||||
9D51565026A36B410075EBC7 /* Socket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Socket.swift; sourceTree = "<group>"; };
|
||||
9D51565126A36B410075EBC7 /* TCPClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TCPClient.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -106,6 +120,7 @@
|
||||
children = (
|
||||
9D5155F226A1EF7B0075EBC7 /* ListenerAppApp.swift */,
|
||||
9D5155F426A1EF7B0075EBC7 /* ContentView.swift */,
|
||||
9D51563626A36AD60075EBC7 /* SwiftSocket */,
|
||||
9D5155F626A1EF7C0075EBC7 /* Assets.xcassets */,
|
||||
9D5155FB26A1EF7C0075EBC7 /* Info.plist */,
|
||||
9D5155F826A1EF7C0075EBC7 /* Preview Content */,
|
||||
@ -147,6 +162,21 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9D51563626A36AD60075EBC7 /* SwiftSocket */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9D51564C26A36B410075EBC7 /* Result.swift */,
|
||||
9D51565026A36B410075EBC7 /* Socket.swift */,
|
||||
9D51564B26A36B410075EBC7 /* SwiftSocket.h */,
|
||||
9D51565126A36B410075EBC7 /* TCPClient.swift */,
|
||||
9D51564F26A36B410075EBC7 /* UDPClient.swift */,
|
||||
9D51564E26A36B410075EBC7 /* ytcpsocket.c */,
|
||||
9D51564D26A36B410075EBC7 /* yudpsocket.c */,
|
||||
9D51563726A36AF20075EBC7 /* ListenerApp-Bridging-Header.h */,
|
||||
);
|
||||
path = SwiftSocket;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@ -215,6 +245,7 @@
|
||||
TargetAttributes = {
|
||||
9D5155EE26A1EF7B0075EBC7 = {
|
||||
CreatedOnToolsVersion = 12.4;
|
||||
LastSwiftMigration = 1240;
|
||||
};
|
||||
9D5155FF26A1EF7C0075EBC7 = {
|
||||
CreatedOnToolsVersion = 12.4;
|
||||
@ -298,8 +329,14 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9D51565726A36B410075EBC7 /* TCPClient.swift in Sources */,
|
||||
9D51565526A36B410075EBC7 /* UDPClient.swift in Sources */,
|
||||
9D51565626A36B410075EBC7 /* Socket.swift in Sources */,
|
||||
9D51565326A36B410075EBC7 /* yudpsocket.c in Sources */,
|
||||
9D51565226A36B410075EBC7 /* Result.swift in Sources */,
|
||||
9D5155F526A1EF7B0075EBC7 /* ContentView.swift in Sources */,
|
||||
9D5155F326A1EF7B0075EBC7 /* ListenerAppApp.swift in Sources */,
|
||||
9D51565426A36B410075EBC7 /* ytcpsocket.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -456,6 +493,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"ListenerApp/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = VD9FGCW36C;
|
||||
@ -468,6 +506,8 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.halcyontouch.ListenerApp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "ListenerApp/SwiftSocket/ListenerApp-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
@ -478,6 +518,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"ListenerApp/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = VD9FGCW36C;
|
||||
@ -490,6 +531,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.halcyontouch.ListenerApp;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "ListenerApp/SwiftSocket/ListenerApp-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
|
@ -17,7 +17,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>39</string>
|
||||
<string>42</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSSpeechRecognitionUsageDescription</key>
|
||||
|
4
ListenerApp/SwiftSocket/ListenerApp-Bridging-Header.h
Normal file
4
ListenerApp/SwiftSocket/ListenerApp-Bridging-Header.h
Normal file
@ -0,0 +1,4 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
28
ListenerApp/SwiftSocket/Result.swift
Normal file
28
ListenerApp/SwiftSocket/Result.swift
Normal file
@ -0,0 +1,28 @@
|
||||
import Foundation
|
||||
|
||||
public enum Result {
|
||||
case success
|
||||
case failure(Error)
|
||||
|
||||
public var isSuccess: Bool {
|
||||
switch self {
|
||||
case .success:
|
||||
return true
|
||||
case .failure:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
public var isFailure: Bool {
|
||||
return !isSuccess
|
||||
}
|
||||
|
||||
public var error: Error? {
|
||||
switch self {
|
||||
case .success:
|
||||
return nil
|
||||
case .failure(let error):
|
||||
return error
|
||||
}
|
||||
}
|
||||
}
|
53
ListenerApp/SwiftSocket/Socket.swift
Normal file
53
ListenerApp/SwiftSocket/Socket.swift
Normal file
@ -0,0 +1,53 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
public typealias Byte = UInt8
|
||||
|
||||
open class Socket {
|
||||
|
||||
public let address: String
|
||||
internal(set) public var port: Int32
|
||||
internal(set) public var fd: Int32?
|
||||
|
||||
public init(address: String, port: Int32) {
|
||||
self.address = address
|
||||
self.port = port
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum SocketError: Error {
|
||||
case queryFailed
|
||||
case connectionClosed
|
||||
case connectionTimeout
|
||||
case unknownError
|
||||
}
|
9
ListenerApp/SwiftSocket/SwiftSocket.h
Normal file
9
ListenerApp/SwiftSocket/SwiftSocket.h
Normal file
@ -0,0 +1,9 @@
|
||||
@import Foundation;
|
||||
|
||||
//! Project version number for SwiftSocket
|
||||
FOUNDATION_EXPORT double SwiftSocketVersionNumber;
|
||||
|
||||
//! Project version string for SwiftSocket
|
||||
FOUNDATION_EXPORT const unsigned char SwiftSocketVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <SwiftSocket_iOS/PublicHeader.h>
|
201
ListenerApp/SwiftSocket/TCPClient.swift
Normal file
201
ListenerApp/SwiftSocket/TCPClient.swift
Normal file
@ -0,0 +1,201 @@
|
||||
//
|
||||
// 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") private func c_ytcpsocket_connect(_ host:UnsafePointer<Byte>,port:Int32,timeout:Int32) -> Int32
|
||||
@_silgen_name("ytcpsocket_close") private func c_ytcpsocket_close(_ fd:Int32) -> Int32
|
||||
@_silgen_name("ytcpsocket_bytes_available") private func c_ytcpsocket_bytes_available(_ fd:Int32) -> Int32
|
||||
@_silgen_name("ytcpsocket_send") private func c_ytcpsocket_send(_ fd:Int32,buff:UnsafePointer<Byte>,len:Int32) -> Int32
|
||||
@_silgen_name("ytcpsocket_pull") private func c_ytcpsocket_pull(_ fd:Int32,buff:UnsafePointer<Byte>,len:Int32,timeout:Int32) -> Int32
|
||||
@_silgen_name("ytcpsocket_listen") private func c_ytcpsocket_listen(_ address:UnsafePointer<Int8>,port:Int32)->Int32
|
||||
@_silgen_name("ytcpsocket_accept") private func c_ytcpsocket_accept(_ onsocketfd:Int32,ip:UnsafePointer<Int8>,port:UnsafePointer<Int32>,timeout:Int32) -> Int32
|
||||
@_silgen_name("ytcpsocket_port") private func c_ytcpsocket_port(_ fd:Int32) -> Int32
|
||||
|
||||
open class TCPClient: Socket {
|
||||
/*
|
||||
* connect to server
|
||||
* return success or fail with message
|
||||
*/
|
||||
open func connect(timeout: Int) -> Result {
|
||||
let rs: Int32 = c_ytcpsocket_connect(self.address, port: Int32(self.port), timeout: Int32(timeout))
|
||||
if rs > 0 {
|
||||
self.fd = rs
|
||||
return .success
|
||||
} else {
|
||||
switch rs {
|
||||
case -1:
|
||||
return .failure(SocketError.queryFailed)
|
||||
case -2:
|
||||
return .failure(SocketError.connectionClosed)
|
||||
case -3:
|
||||
return .failure(SocketError.connectionTimeout)
|
||||
default:
|
||||
return .failure(SocketError.unknownError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* close socket
|
||||
* return success or fail with message
|
||||
*/
|
||||
open func close() {
|
||||
guard let fd = self.fd else { return }
|
||||
|
||||
_ = c_ytcpsocket_close(fd)
|
||||
self.fd = nil
|
||||
}
|
||||
|
||||
/*
|
||||
* send data
|
||||
* return success or fail with message
|
||||
*/
|
||||
open func send(data: [Byte]) -> Result {
|
||||
guard let fd = self.fd else { return .failure(SocketError.connectionClosed) }
|
||||
|
||||
let sendsize: Int32 = c_ytcpsocket_send(fd, buff: data, len: Int32(data.count))
|
||||
if Int(sendsize) == data.count {
|
||||
return .success
|
||||
} else {
|
||||
return .failure(SocketError.unknownError)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* send string
|
||||
* return success or fail with message
|
||||
*/
|
||||
open func send(string: String) -> Result {
|
||||
guard let fd = self.fd else { return .failure(SocketError.connectionClosed) }
|
||||
|
||||
let sendsize = c_ytcpsocket_send(fd, buff: string, len: Int32(strlen(string)))
|
||||
if sendsize == Int32(strlen(string)) {
|
||||
return .success
|
||||
} else {
|
||||
return .failure(SocketError.unknownError)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* send nsdata
|
||||
*/
|
||||
open func send(data: Data) -> Result {
|
||||
guard let fd = self.fd else { return .failure(SocketError.connectionClosed) }
|
||||
|
||||
var buff = [Byte](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 .success
|
||||
} else {
|
||||
return .failure(SocketError.unknownError)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* read data with expect length
|
||||
* return success or fail with message
|
||||
*/
|
||||
open func read(_ expectlen:Int, timeout:Int = -1) -> [Byte]? {
|
||||
guard let fd:Int32 = self.fd else { return nil }
|
||||
|
||||
var buff = [Byte](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: [Byte] = Array(rs)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
/*
|
||||
* gets byte available for reading
|
||||
*/
|
||||
open func bytesAvailable() -> Int32? {
|
||||
guard let fd:Int32 = self.fd else { return nil }
|
||||
|
||||
let bytesAvailable = c_ytcpsocket_bytes_available(fd);
|
||||
|
||||
if (bytesAvailable < 0) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return bytesAvailable
|
||||
}
|
||||
}
|
||||
|
||||
open class TCPServer: Socket {
|
||||
|
||||
open func listen() -> Result {
|
||||
let fd = c_ytcpsocket_listen(self.address, port: Int32(self.port))
|
||||
if fd > 0 {
|
||||
self.fd = fd
|
||||
|
||||
// If port 0 is used, get the actual port number which the server is listening to
|
||||
if (self.port == 0) {
|
||||
let p = c_ytcpsocket_port(fd)
|
||||
if (p == -1) {
|
||||
return .failure(SocketError.unknownError)
|
||||
} else {
|
||||
self.port = p
|
||||
}
|
||||
}
|
||||
|
||||
return .success
|
||||
} else {
|
||||
return .failure(SocketError.unknownError)
|
||||
}
|
||||
}
|
||||
|
||||
open func accept(timeout :Int32 = 0) -> 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, timeout: timeout)
|
||||
|
||||
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: port)
|
||||
client.fd = clientfd
|
||||
|
||||
return client
|
||||
}
|
||||
|
||||
open func close() {
|
||||
guard let fd: Int32=self.fd else { return }
|
||||
|
||||
_ = c_ytcpsocket_close(fd)
|
||||
self.fd = nil
|
||||
}
|
||||
}
|
185
ListenerApp/SwiftSocket/UDPClient.swift
Normal file
185
ListenerApp/SwiftSocket/UDPClient.swift
Normal file
@ -0,0 +1,185 @@
|
||||
//
|
||||
// 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("yudpsocket_server") func c_yudpsocket_server(_ host:UnsafePointer<Int8>,port:Int32) -> Int32
|
||||
@_silgen_name("yudpsocket_recive") func c_yudpsocket_recive(_ fd:Int32,buff:UnsafePointer<Byte>,len:Int32,ip:UnsafePointer<Int8>,port:UnsafePointer<Int32>) -> Int32
|
||||
@_silgen_name("yudpsocket_close") func c_yudpsocket_close(_ fd:Int32) -> Int32
|
||||
@_silgen_name("yudpsocket_client") func c_yudpsocket_client() -> Int32
|
||||
@_silgen_name("yudpsocket_get_server_ip") func c_yudpsocket_get_server_ip(_ host:UnsafePointer<Int8>,ip:UnsafePointer<Int8>) -> Int32
|
||||
@_silgen_name("yudpsocket_sentto") func c_yudpsocket_sentto(_ fd:Int32,buff:UnsafePointer<Byte>,len:Int32,ip:UnsafePointer<Int8>,port:Int32) -> Int32
|
||||
@_silgen_name("enable_broadcast") func c_enable_broadcast(_ fd:Int32)
|
||||
|
||||
open class UDPClient: Socket {
|
||||
public override init(address: String, port: Int32) {
|
||||
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: [Byte]) -> Result {
|
||||
guard let fd = self.fd else { return .failure(SocketError.connectionClosed) }
|
||||
|
||||
let sendsize: Int32 = c_yudpsocket_sentto(fd, buff: data, len: Int32(data.count), ip: self.address, port: Int32(self.port))
|
||||
if Int(sendsize) == data.count {
|
||||
return .success
|
||||
} else {
|
||||
return .failure(SocketError.unknownError)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* send string
|
||||
* return success or fail with message
|
||||
*/
|
||||
open func send(string: String) -> Result {
|
||||
guard let fd = self.fd else { return .failure(SocketError.connectionClosed) }
|
||||
|
||||
let sendsize = c_yudpsocket_sentto(fd, buff: string, len: Int32(strlen(string)), ip: address, port: port)
|
||||
if sendsize == Int32(strlen(string)) {
|
||||
return .success
|
||||
} else {
|
||||
return .failure(SocketError.unknownError)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* enableBroadcast
|
||||
*/
|
||||
open func enableBroadcast() {
|
||||
guard let fd: Int32 = self.fd else { return }
|
||||
|
||||
c_enable_broadcast(fd)
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* send nsdata
|
||||
*/
|
||||
open func send(data: Data) -> Result {
|
||||
guard let fd = self.fd else { return .failure(SocketError.connectionClosed) }
|
||||
|
||||
var buff = [Byte](repeating: 0x0,count: data.count)
|
||||
(data as NSData).getBytes(&buff, length: data.count)
|
||||
let sendsize = c_yudpsocket_sentto(fd, buff: buff, len: Int32(data.count), ip: address, port: port)
|
||||
if sendsize == Int32(data.count) {
|
||||
return .success
|
||||
} else {
|
||||
return .failure(SocketError.unknownError)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO add multycast and boardcast
|
||||
open func recv(_ expectlen: Int) -> ([Byte]?, String, Int) {
|
||||
guard let fd = self.fd else {
|
||||
return (nil, "no ip", 0)
|
||||
}
|
||||
var buff: [Byte] = [Byte](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)
|
||||
let address = String(cString: remoteipbuff, encoding: String.Encoding.utf8) ?? ""
|
||||
|
||||
if readLen <= 0 {
|
||||
return (nil, address, port)
|
||||
}
|
||||
|
||||
let data: [Byte] = Array(buff[0..<Int(readLen)])
|
||||
return (data, address, port)
|
||||
}
|
||||
|
||||
open func close() {
|
||||
guard let fd = self.fd else { return }
|
||||
|
||||
_ = c_yudpsocket_close(fd)
|
||||
self.fd = nil
|
||||
}
|
||||
//TODO add multycast and boardcast
|
||||
}
|
||||
|
||||
open class UDPServer: Socket {
|
||||
|
||||
public override init(address: String, port: Int32) {
|
||||
super.init(address: address, port: port)
|
||||
|
||||
let fd = c_yudpsocket_server(address, port: port)
|
||||
if fd > 0 {
|
||||
self.fd = fd
|
||||
}
|
||||
}
|
||||
|
||||
//TODO add multycast and boardcast
|
||||
open func recv(_ expectlen: Int) -> ([Byte]?, String, Int) {
|
||||
if let fd = self.fd {
|
||||
var buff: [Byte] = [Byte](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, address, port)
|
||||
}
|
||||
|
||||
let rs = buff[0...Int(readLen-1)]
|
||||
let data: [Byte] = Array(rs)
|
||||
return (data, address, port)
|
||||
}
|
||||
|
||||
return (nil, "no ip", 0)
|
||||
}
|
||||
|
||||
open func close() {
|
||||
guard let fd = self.fd else { return }
|
||||
|
||||
_ = c_yudpsocket_close(fd)
|
||||
self.fd = nil
|
||||
}
|
||||
}
|
223
ListenerApp/SwiftSocket/ytcpsocket.c
Normal file
223
ListenerApp/SwiftSocket/ytcpsocket.c
Normal file
@ -0,0 +1,223 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <dirent.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
void ytcpsocket_set_block(int socket, int on) {
|
||||
int flags;
|
||||
flags = fcntl(socket, F_GETFL, 0);
|
||||
if (on == 0) {
|
||||
fcntl(socket, F_SETFL, flags | O_NONBLOCK);
|
||||
} else {
|
||||
flags &= ~ O_NONBLOCK;
|
||||
fcntl(socket, F_SETFL, flags);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
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) {
|
||||
close(sockfd);
|
||||
return -2;
|
||||
} else if(retval == 0) {//timeout
|
||||
close(sockfd);
|
||||
return -3;
|
||||
} else {
|
||||
int error = 0;
|
||||
int errlen = sizeof(error);
|
||||
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&errlen);
|
||||
if (error != 0) {
|
||||
close(sockfd);
|
||||
return -4;//connect fail
|
||||
}
|
||||
|
||||
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) {
|
||||
int readlen = 0;
|
||||
int datalen = 0;
|
||||
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) {
|
||||
return ret; // select-call failed or timeout occurred (before anything was sent)
|
||||
}
|
||||
}
|
||||
// use loop to make sure receive all data
|
||||
do {
|
||||
readlen = (int)read(socketfd, data + datalen, len - datalen);
|
||||
if (readlen > 0) {
|
||||
datalen += readlen;
|
||||
}
|
||||
} while (readlen > 0);
|
||||
|
||||
return datalen;
|
||||
}
|
||||
|
||||
int ytcpsocket_bytes_available(int socketfd) {
|
||||
int count;
|
||||
int callResult = ioctl(socketfd, FIONREAD, &count);
|
||||
|
||||
if (callResult < 0) {
|
||||
return callResult;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return byteswrite;
|
||||
}
|
||||
|
||||
//return socket fd
|
||||
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));
|
||||
|
||||
//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(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) {
|
||||
return socketfd;
|
||||
} else {
|
||||
return -2;//listen error
|
||||
}
|
||||
} else {
|
||||
return -1;//bind error
|
||||
}
|
||||
}
|
||||
|
||||
//return client socket fd
|
||||
int ytcpsocket_accept(int onsocketfd, char *remoteip, int *remoteport, int timeouts) {
|
||||
socklen_t clilen;
|
||||
struct sockaddr_in cli_addr;
|
||||
clilen = sizeof(cli_addr);
|
||||
fd_set fdset;
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(onsocketfd, &fdset);
|
||||
struct timeval *timeptr = NULL;
|
||||
struct timeval timeout;
|
||||
if (timeouts > 0) {
|
||||
timeout.tv_sec = timeouts;
|
||||
timeout.tv_usec = 0;
|
||||
timeptr = &timeout;
|
||||
}
|
||||
int status = select(FD_SETSIZE, &fdset, NULL, NULL, timeptr);
|
||||
if (status != 1) {
|
||||
return -1;
|
||||
}
|
||||
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) {
|
||||
int set = 1;
|
||||
setsockopt(newsockfd, SOL_SOCKET, SO_NOSIGPIPE, (void*) &set, sizeof(int));
|
||||
return newsockfd;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//return socket port
|
||||
int ytcpsocket_port(int socketfd) {
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
if (getsockname(socketfd, (struct sockaddr *)&sin, &len) == -1) {
|
||||
return -1;
|
||||
} else {
|
||||
return ntohs(sin.sin_port);
|
||||
}
|
||||
}
|
139
ListenerApp/SwiftSocket/yudpsocket.c
Normal file
139
ListenerApp/SwiftSocket/yudpsocket.c
Normal file
@ -0,0 +1,139 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#define yudpsocket_buff_len 8192
|
||||
|
||||
//return socket fd
|
||||
int yudpsocket_server(const char *address, int port) {
|
||||
|
||||
//create socket
|
||||
int socketfd=socket(AF_INET, SOCK_DGRAM, 0);
|
||||
int reuseon = 1;
|
||||
int r = -1;
|
||||
|
||||
//bind
|
||||
struct sockaddr_in serv_addr;
|
||||
memset( &serv_addr, '\0', sizeof(serv_addr));
|
||||
serv_addr.sin_len = sizeof(struct sockaddr_in);
|
||||
serv_addr.sin_family = AF_INET;
|
||||
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(address);
|
||||
serv_addr.sin_port = htons(port);
|
||||
}
|
||||
|
||||
if (r == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = bind(socketfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
|
||||
if (r == 0) {
|
||||
return socketfd;
|
||||
} 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);
|
||||
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);
|
||||
memcpy(remoteip, clientip, strlen(clientip));
|
||||
*remoteport = cli_addr.sin_port;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int yudpsocket_close(int socket_fd) {
|
||||
return close(socket_fd);
|
||||
}
|
||||
|
||||
//return socket fd
|
||||
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));
|
||||
|
||||
//disable SIGPIPE as we'll handle send errors ourselves
|
||||
int noSigPipe = 1;
|
||||
setsockopt(socketfd, SOL_SOCKET, SO_NOSIGPIPE, &noSigPipe, sizeof(noSigPipe));
|
||||
|
||||
return socketfd;
|
||||
}
|
||||
|
||||
//enable broadcast
|
||||
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) {
|
||||
struct hostent *hp;
|
||||
struct sockaddr_in address;
|
||||
|
||||
hp = gethostbyname(host);
|
||||
if (hp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user