Stack Overflow Asked by Mr. Park on November 7, 2021
I send messages to applications running on remote computers.
I send messages this ways.
c#:
void web_data_work()
{
try
{
TcpClient client = new TcpClient(address, port);
Byte[] data = Encoding.UTF8.GetBytes(string.Format("{0}", message));
NetworkStream stream = client.GetStream();
try
{
if (message != "")
{
stream.Write(data, 0, data.Length);
Byte[] readingData = new Byte[256];
String responseData = String.Empty;
StringBuilder completeMessage = new StringBuilder();
int numberOfBytesRead = 0;
do
{
numberOfBytesRead = stream.Read(readingData, 0, readingData.Length);
completeMessage.AppendFormat("{0}", Encoding.UTF8.GetString(readingData, 0, numberOfBytesRead));
}
while (stream.DataAvailable);
responseData = completeMessage.ToString();
this.Invoke((MethodInvoker)delegate ()
{
output_list.Items.Add(string.Format("Sended – {0}", responseData));
message = "";
});
}
}
finally
{
stream.Close();
client.Close();
}
}
catch
{
this.Invoke((MethodInvoker)delegate ()
{
output_list.Items.Add("Not sended");
message = "";
});
}
}
swift:
func web_data_work()
{
let address = address_box.stringValue
let port = port_box.intValue
let task = URLSession.shared.streamTask(withHostName: address, port: Int(port))
let data = message.data(using: .utf8)!
task.write(data as Data, timeout: 0)
{
error in
//om = "Not sended"
//self.output_message()
}
task.resume()
}
In c# i can read messages using TcpListener, how do i do it in swift?
Only two parameters are used:
"address" – ip address of the computer to which messages are sent and which is listened to by the TcpListener of that computer.
"port" – port of the sending and receiving between computers.
P.S. Preferably without additional libraries.
You can achieve this with just two classes: SocketPort
& FileHandle
.
Before you copy & paste the example below, please, read my comments at the end.
import Cocoa
class TcpEchoClient {
var readToEndOfFileCompletionHandler: (() -> Void)?
let fileHandle: FileHandle
var observer: NSObjectProtocol?
init(fileHandle: FileHandle) {
self.fileHandle = fileHandle
// Register observer for the data & EOF
self.observer = NotificationCenter.default.addObserver(forName: .NSFileHandleReadToEndOfFileCompletion,
object: fileHandle,
queue: OperationQueue.main) { [weak self] note in
self?.handleReadToEndOfFileCompletion(notification: note)
}
// Instruct the handle to read till the EOF & notify
fileHandle.readToEndOfFileInBackgroundAndNotify()
}
func handleReadToEndOfFileCompletion(notification note: Notification) {
defer {
// No matter what happens, call the completion handle by the end
readToEndOfFileCompletionHandler?()
}
// Is there an error?
if let errorCode = note.userInfo?["NSFileHandleError"] as? NSNumber {
print("Client (fileHandle.fileDescriptor) error: File handle error (errorCode.intValue)")
return
}
// No error, we should have data available
guard let data = note.userInfo?[NSFileHandleNotificationDataItem] as? Data else {
print("Client (fileHandle.fileDescriptor) error: Unable to get data")
return
}
// Convert them to UTF-8 string
guard let text = String(data: data, encoding: .utf8) else {
print("Client (fileHandle.fileDescriptor) error: Unable to convert data to UTF-8 string")
return
}
// Print the text
print("Client (fileHandle.fileDescriptor) received: (text)")
}
deinit {
// Remove observer for the data & EOF
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
// Close the handle
try? fileHandle.close()
}
}
class TcpServer {
let port: SocketPort
let fileHandle: FileHandle
var clients: Dictionary<Int32, TcpEchoClient>
var observer: NSObjectProtocol?
init?(tcpPort: UInt16) {
guard let socketPort = SocketPort(tcpPort: tcpPort) else {
return nil
}
// Keep the socket port around otherwise you'll get error 38
port = socketPort
// No clients for now
clients = [:]
// Create handle from the socket
fileHandle = FileHandle(fileDescriptor: port.socket)
// Register observer for the connection accepted
observer = NotificationCenter.default.addObserver(forName: .NSFileHandleConnectionAccepted,
object: fileHandle,
queue: OperationQueue.main) { [weak self] note in
if let handle = note.object as? FileHandle {
// Ask immediately for another accepted connection notification
handle.acceptConnectionInBackgroundAndNotify()
}
self?.handleConnectionAccepted(notification: note)
}
// Instruct the handle to accept connection & notify
fileHandle.acceptConnectionInBackgroundAndNotify()
}
func handleConnectionAccepted(notification note: Notification) {
// Is there an error?
if let errorCode = note.userInfo?["NSFileHandleError"] as? NSNumber {
print("Server error: File handle error (errorCode.intValue)")
return
}
// No, we should have received the client file handle
guard let clientFileHandle = note.userInfo?[NSFileHandleNotificationFileHandleItem] as? FileHandle else {
print("Server error: Unable to get accepted connection file handle")
return
}
let fileDescriptor = clientFileHandle.fileDescriptor
// Create new client from the file handle
let client = TcpEchoClient(fileHandle: clientFileHandle)
// Once it finishes, remove it from the clients dictionary
client.readToEndOfFileCompletionHandler = { [weak self] in
guard let self = self else { return }
self.clients.removeValue(forKey: fileDescriptor)
print("Server: Client removed (fileDescriptor) (total (self.clients.count))")
}
// Store the client in the clients dictionary
clients[fileDescriptor] = client
print("Server: New client (fileDescriptor) added (total (self.clients.count))")
}
deinit {
// Remove all clients
clients.removeAll()
// Close the file handle
try? fileHandle.close()
// Invalidate the socket port
port.invalidate()
// Remove connection accepted observer
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
}
}
Then create a property (var server: TcpServer?
) and initialize it (server = TcpServer(tcpPort: 8080)
).
Test:
parallel -j 1 echo -n Foo '|' nc 127.0.0.1 8080 ::: {1..4}
Console output:
Server: New client 7 added (total 1)
Client 7 received: Foo
Server: Client removed 7 (total 0)
Server: New client 7 added (total 1)
Client 7 received: Foo
Server: Client removed 7 (total 0)
Server: New client 7 added (total 1)
Client 7 received: Foo
Server: Client removed 7 (total 0)
Server: New client 7 added (total 1)
Client 7 received: Foo
Server: Client removed 7 (total 0)
Comments:
parallel
test command.
Answered by zrzka on November 7, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP