16

文字列をサーバーに送信できるように、iOS デバイスの単純な TCP の例を知っている人はいますか。次のライブラリhttps://github.com/robbiehanson/CocoaAsyncSocketを見てきましたが、非常に冗長に見えます。

私が本当に欲しいのは、IPアドレスとポート番号に接続し、このアドレスにデータの文字列を送信する簡単な方法を持つことだけです. これを行う簡単な方法を知っている人はいますか?

4

7 に答える 7

28

SocketConnectionVC.h

#import <UIKit/UIKit.h>

@interface SocketConnectionVC : UIViewController<NSStreamDelegate>
{
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;

    NSInputStream   *inputStream;
    NSOutputStream  *outputStream;

    NSMutableArray  *messages;
}

@property (weak, nonatomic) IBOutlet UITextField *ipAddressText;
@property (weak, nonatomic) IBOutlet UITextField *portText;
@property (weak, nonatomic) IBOutlet UITextField *dataToSendText;
@property (weak, nonatomic) IBOutlet UITextView *dataRecievedTextView;
@property (weak, nonatomic) IBOutlet UILabel *connectedLabel;


@end

SocketConnectionVC.m

#import "SocketConnectionVC.h"

@interface SocketConnectionVC ()

@end

@implementation SocketConnectionVC

- (void)viewDidLoad {
    [super viewDidLoad];

    _connectedLabel.text = @"Disconnected";
}

- (IBAction) sendMessage {

    NSString *response  = [NSString stringWithFormat:@"msg:%@", _dataToSendText.text];
    NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];
    [outputStream write:[data bytes] maxLength:[data length]];

}

- (void) messageReceived:(NSString *)message {

    [messages addObject:message];

    _dataRecievedTextView.text = message;
    NSLog(@"%@", message);
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {

    NSLog(@"stream event %lu", streamEvent);

    switch (streamEvent) {

        case NSStreamEventOpenCompleted:
            NSLog(@"Stream opened");
            _connectedLabel.text = @"Connected";
            break;
        case NSStreamEventHasBytesAvailable:

            if (theStream == inputStream)
            {
                uint8_t buffer[1024];
                NSInteger len;

                while ([inputStream hasBytesAvailable])
                {
                    len = [inputStream read:buffer maxLength:sizeof(buffer)];
                    if (len > 0)
                    {
                        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];

                        if (nil != output)
                        {
                            NSLog(@"server said: %@", output);
                            [self messageReceived:output];
                        }
                    }
                }
            }
            break;

        case NSStreamEventHasSpaceAvailable:
            NSLog(@"Stream has space available now");
            break;

        case NSStreamEventErrorOccurred:
             NSLog(@"%@",[theStream streamError].localizedDescription);
            break;

        case NSStreamEventEndEncountered:

            [theStream close];
            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            _connectedLabel.text = @"Disconnected";
            NSLog(@"close stream");
            break;
        default:
            NSLog(@"Unknown event");
    }

}

- (IBAction)connectToServer:(id)sender {

    NSLog(@"Setting up connection to %@ : %i", _ipAddressText.text, [_portText.text intValue]);
    CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef) _ipAddressText.text, [_portText.text intValue], &readStream, &writeStream);

    messages = [[NSMutableArray alloc] init];

    [self open];
}

- (IBAction)disconnect:(id)sender {

    [self close];
}

- (void)open {

    NSLog(@"Opening streams.");

    outputStream = (__bridge NSOutputStream *)writeStream;
    inputStream = (__bridge NSInputStream *)readStream;

    [outputStream setDelegate:self];
    [inputStream setDelegate:self];

    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [outputStream open];
    [inputStream open];

    _connectedLabel.text = @"Connected";
}

- (void)close {
    NSLog(@"Closing streams.");
    [inputStream close];
    [outputStream close];
    [inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [inputStream setDelegate:nil];
    [outputStream setDelegate:nil];
    inputStream = nil;
    outputStream = nil;

    _connectedLabel.text = @"Disconnected";
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

この SocketConnectionVC の ui のスナップショット ここに画像の説明を入力

次の手順に従ってください

1- input the ip on ipAdress textfield
2- input the port on port textfield
3- press connect button
4- (make sure the ip address and port is correct and the open of stream is fine. you can show the status of stream on console of Xcode)
5- input data to send to server
6- press send button
7- you can show the received message from server on the text view above connect button
于 2015-10-30T15:03:40.830 に答える
2

ここで試してみてください:http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server

Ray は、Python + iOS クライアント アプリケーションを使用してカスタム サーバーを構築する良い例を挙げています。彼は、iOS トピックに関する非常に優れた一連のチュートリアルを持っています。彼のサイトにアクセスする価値があります。

于 2013-09-25T11:19:09.210 に答える
0
import Network


@objc protocol TCPConnectionDelegate {
    @objc optional func deviceStatusUpdated(isUpdated:Bool)
    @objc optional func deviceSwitchToNetwork(deviceId:String)
    @objc optional func TcpConnectionState(state:String,ip:String)
}

class TCPConnection:NSObject{

    var delegate:TCPConnectionDelegate?
    var connection: NWConnection?

    final func start(host:NWEndpoint.Host) {
        connection = NWConnection(host: host, port: 1234, using: .tcp)
        connection!.stateUpdateHandler = self.stateDidChange(to:)
        self.setupReceive(on: connection!)
        connection!.start(queue: .main)
        //self.connection = connection
    }
    
    func stateDidChange(to state: NWConnection.State) {
        var ipAddressWithPort = connection!.endpoint.debugDescription
        let ip = ipAddressWithPort.components(separatedBy: ":")
        switch state {
        case .setup:
            break
        case .waiting(let error):
            print("Errrooor",error)
            self.delegate?.TcpConnectionState!(state: error.localizedDescription, ip: ip[0])
        //self.connectionDidFail(error: error)
        case .preparing:
            break
        case .ready:
            print("Readddy",connection?.endpoint.debugDescription)
            
            print("IPAADERESS",ip[0])
            self.delegate?.TcpConnectionState!(state: "Connected",ip: ip[0])
        case .failed(let error):
            print("FAiled",error)
            self.delegate?.TcpConnectionState!(state: error.localizedDescription, ip: ip[0])
        case .cancelled:
            break
        }
      
    }
    
    func setupReceive(on connection: NWConnection) {
        connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { (data, contentContext, isComplete, error) in
            if let data = data, !data.isEmpty {
                
                print("Received:", String(data: data, encoding: .utf8) )
                let stringData = String(data: data, encoding: .utf8)
                let data = stringData!.data(using: .utf8)
                do {
                    let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String:Any]
                    
                   
                    
                    
                    print("REsponseeeeData",json)
                }catch{
                    
                }
                
            }
            if isComplete {
                self.connectionDidEnd()
            } else if let error = error {
                self.connectionDidFail(error: error)
            } else {
                self.setupReceive(on: connection)
            }
        }
    }
    var didStopCallback: ((Error?) -> Void)? = nil
    private func connectionDidFail(error: Error) {
        print("connection did fail, error: \(error)")
        stop(error: error)
    }

    private func connectionDidEnd() {
        print("connection  did end")
        stop(error: nil)
    }
    private func stop(error: Error?) {
        connection!.stateUpdateHandler = nil
        connection!.cancel()
        if let didStopCallback = didStopCallback {
            self.didStopCallback = nil
            didStopCallback(error)
        }
    }
    
    func sendStreamOriented(connection: NWConnection, data: Data) {
        connection.send(content: data, completion: .contentProcessed({ error in
            if let error = error {
                print("Errrorrrr",error)
                //  self.connectionDidFail(error: error)
            }
        }))
    }
    
    func sendEndOfStream(connection: NWConnection) {
        connection.send(content: nil, contentContext: .defaultStream, isComplete: true, completion: .contentProcessed({ error in
            if let error = error {
                print("Errrorrrr11111",error)
                // self.connectionDidFail(error: error)
            }
        }))
    }
    
    func sendMsg(message: [String:Any]) {
        let json = try? JSONSerialization.data(withJSONObject: message, options: .prettyPrinted)
        guard let jsnStr = String(data: json!, encoding: .utf8) else { return }
        print("ekdhkhfkehflhf",jsnStr)
        
        let msg = jsnStr + "\r\n"
        let data: Data? = msg.data(using: .utf8)
        connection!.send(content: data, completion: .contentProcessed { (sendError) in
            if let sendError = sendError {
                print("\(sendError)")
            }
            })
        self.setupReceive(on: connection!)
    }
    
    func cancel() {
        connection!.cancel()
    }
    

}
于 2020-11-23T13:49:29.403 に答える
0

Apple のサンプルは、次のようなさまざまな Apple API を使用して TCP 接続を実行する方法を示しています。

  1. ソケットストリーム/ストリーム
  2. URLSessionStreamTask
  3. BSD ソケット
  4. NWTCP接続
于 2021-05-12T02:03:53.657 に答える