首页 > 解决方案 > nw_connection_receive 仅从 UDP 套接字连接接收 9216 个字节

问题描述

我正在尝试通过 UDP 套接字从单独的计算机接收大约 45kb 的数据。为此,我使用 Apple 的网络框架,并创建一个网络侦听器,等待连接,然后调用 nw_connection_receive 接收数据包。我注意到的是它只返回 9216 个字节。是否有理由或可能调用来增加正在使用的任何缓冲区?9kb 似乎很小?

我的代码如下:

@import Network;
@import NetworkExtension;
#import "UdpSocket.h"


@implementation UdpSocket

-(id)initAsOutbound:(NSString*)host toPort:(int)port
{
    self = [super init];
    if (self)
    {
        self.IsConnected = NO;
        [self SetupOutboundConnection:nw_endpoint_create_host([host UTF8String], [[NSString stringWithFormat:@"%d", port] UTF8String])];
    }
    return self;
}

-(id)initAsInbound:(int)port
{
    self = [super init];
    if (self)
    {
        self.IsConnected = NO;
        [self SetupInboundListener:port];
    }
    return self;
}


-(void)SetupInboundListener:(int)port
{
    nw_endpoint_t local_endpoint = nw_endpoint_create_host("::", [[NSString stringWithFormat:@"%d", port] UTF8String]);
    self.parameters = nw_parameters_create_secure_udp( NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION);
    nw_parameters_set_local_endpoint(self.parameters, local_endpoint);
   
    self.listener = nw_listener_create(self.parameters);

    nw_listener_set_queue(self.listener, dispatch_get_main_queue());
    
    nw_listener_set_state_changed_handler(self.listener, ^(nw_listener_state_t state, nw_error_t error)
    { dispatch_async(dispatch_get_main_queue(), ^{ [self OnListenerChangedStates:state]; }); });
    
    nw_listener_set_new_connection_handler(self.listener, ^(nw_connection_t connection)
    { dispatch_async(dispatch_get_main_queue(), ^{ [self OnNewConnections:connection]; }); });
    
    nw_listener_start(self.listener);
}

-(void)SetupOutboundConnection:(nw_endpoint_t)destination
{
    self.parameters = nw_parameters_create_secure_udp( NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION);
    self.connection = nw_connection_create(destination, self.parameters);
    nw_connection_set_queue(self.connection, dispatch_get_main_queue());
 
    nw_connection_set_state_changed_handler(self.connection, ^(nw_connection_state_t state, nw_error_t error)
    { dispatch_async(dispatch_get_main_queue(), ^{ [self OnConnectionChangedState:state]; }); });
        
    nw_connection_start(self.connection);
}


-(void)OnNewConnections:(nw_connection_t)connection
{
    self.connection = connection;
    nw_connection_set_queue(connection, dispatch_get_main_queue());
    nw_connection_start(connection);
    
    self.IsConnected = YES;
    NSLog(@"Socket connected");
    [self StartListeningForMessages];
}


-(void)OnListenerChangedStates:(nw_listener_state_t)newState
{
    switch (newState)
    {
        case nw_listener_state_waiting:
            NSLog(@"Server Waiting");
            break;
        case nw_listener_state_failed:
            NSLog(@"Server Failed");
            break;
        case nw_listener_state_ready:
            NSLog(@"Server is ready");
            break;
        default:
            break;
    }
}

-(void)OnConnectionChangedState:(nw_connection_state_t)newState
{
    switch (newState)
    {
        case nw_connection_state_waiting:
            NSLog(@"Waiting");
            break;
        case nw_connection_state_failed:
            NSLog(@"Failed");
            break;
        case nw_connection_state_ready:
        {
            self.IsConnected = YES;
            NSLog(@"Connection is ready");
        }
            break;
        case nw_connection_state_cancelled:
            NSLog(@"Connection is cancelled");
            nw_connection_cancel(self.connection);
            break;
        default:
            break;
    }
}


-(void)StartListeningForMessages
{
    if ( self.IsConnected && self.connection != nil )
    {
        nw_connection_receive(self.connection, 1, UINT32_MAX,
                              ^(dispatch_data_t content, nw_content_context_t context, bool is_complete, nw_error_t receive_error)
        {
            if ( is_complete )
            {
                NSLog(@"is_complete");
            }
            if( receive_error == nil )
            {
                
                [self OnDataReceived:[UdpSocket NSDataFromDispatchData:content]];
                [self StartListeningForMessages];
            }
        });
    }
}


-(void)OnDataReceived:(NSData*)data
{
    NSLog(@"OnDataReceived %d bytes", (int)[data length]);
}

-(void)SendMessage:(NSString*)message
{
    if ( self.IsConnected )
    {
        NSData* sendMessage = [message dataUsingEncoding:NSUTF8StringEncoding];
        dispatch_data_t data = [UdpSocket DispatchDataFromNSData:sendMessage];
        nw_connection_send(self.connection, data, NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, true, ^(nw_error_t  _Nullable error)
        {
            NSLog(@"Message sent");
        });
    }
}

+(dispatch_data_t)DispatchDataFromNSData:(NSData*)nsdata
{
    if (nsdata == nil)
    { return nil; }
    
    Byte byte[nsdata.length];
    [nsdata getBytes:byte length:nsdata.length];
    dispatch_data_t data = dispatch_data_create(byte, nsdata.length, nil, DISPATCH_DATA_DESTRUCTOR_DEFAULT);
    return data;
}

+(NSData*)NSDataFromDispatchData:(dispatch_data_t)dispatchData
{
    if ( dispatchData == nil )
    { return nil; }
    
    const void *buffer = NULL;
    size_t size = 0;
    dispatch_data_t new_data_file = dispatch_data_create_map(dispatchData, &buffer, &size);
    NSLog(@"[%d] bytes", (int)size);
    if ( new_data_file )
    {
        NSData *nsdata = [[NSData alloc] initWithBytes:buffer length:size];
        return nsdata;
    }
    
    return nil;
}

@end

输出:

Server Waiting
Server is ready
Socket connected
is_complete
OnDataReceived 9216 bytes

标签: iosobjective-c

解决方案


推荐阅读