GCDAsyncSocket:android主机无法获取iOS客户端编写的数据

时间:2016-05-17 05:21:47

标签: android ios gcdasyncsocket

我正在开发一个需要从Android主机应用程序发送和接收消息的iOs应用程序。

Android主机应用程序以编程方式创建Wifi Hotpot,iOS设备将从设置加入它。

首先,我尝试使用Apple的NSOutputStream类来写入主机。但没有运气。 现在,我正在运行GCDAsyncSocket的ConnectionTest示例。但是android主机无法读取iOS客户端编写的数据。

建立连接的代码

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

dispatch_queue_t mainQueue = dispatch_get_main_queue();

    asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];

NSString *host = HOST;
        uint16_t port = PORT;

        DDLogInfo(@"Connecting to \"%@\" on port %hu...", host, port);
        self.viewController.label.text = @"Connecting...";

        NSError *error = nil;
        if (![asyncSocket connectToHost:host onPort:port error:&error])
        {
            DDLogError(@"Error connecting: %@", error);
            self.viewController.label.text = @"Oops";
        }
// Add the view controller's view to the window and display.
    [self.window addSubview:self.viewController.view];
    [self.window makeKeyAndVisible];

    return YES;
}

建立连接时编写数据的代码

  - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
    {
        DDLogInfo(@"socket:%p didConnectToHost:%@ port:%hu", sock, host, port);
        self.viewController.label.text = @"Connected";

        NSString *requestStr = @"girsh:";
            NSMutableData *requestData = [[NSMutableData alloc] initWithData:[requestStr dataUsingEncoding:NSUTF8StringEncoding]];

            [requestData appendData:[GCDAsyncSocket CRLFData]];

            [sock writeData:requestData withTimeout:1 tag:1];
}

***** ANDROID CODE ********

 private void startHotspot() {
//////////////////
        if (wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(false);
        }
        Method[] wmMethods = wifiManager.getClass().getDeclaredMethods();
        boolean methodFound = false;
        for (Method method : wmMethods) {
            if (method.getName().equals("setWifiApEnabled")) {
                methodFound = true;
                Calendar calendar = Calendar.getInstance();

                WifiConfiguration netConfig = new WifiConfiguration();
                netConfig.SSID = "AISTT" + "What_Next" + calendar.get(Calendar.MINUTE) + "." + calendar.get(Calendar.SECOND);
                netConfig.preSharedKey = "DataAnywhere";//getString(R.string.password);  //// Password
                netConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
                netConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
                try {
                    boolean apstatus = (Boolean) method.invoke(wifiManager, netConfig, true);

                    for (Method isWifiApEnabledmethod : wmMethods) {
                        if (isWifiApEnabledmethod.getName().equals("isWifiApEnabled")) {
                            while (!(Boolean) isWifiApEnabledmethod.invoke(wifiManager)) {
                            }

                            for (Method method1 : wmMethods) {
                                if (method1.getName().equals("getWifiApState")) {
                                    int apstate;
                                    apstate = (Integer) method1.invoke(wifiManager);
                                    Log.i(this.getClass().toString(), "Apstate ::: " + apstate);
                                }
                            }
                        }
                    }
                    if (apstatus) {
                        Log.d("Splash Activity", "Access Point created");
                    } else {
                        Log.d("Splash Activity", "Access Point creation failed");
                    }

                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
        if (!methodFound) {
            Log.d("Splash Activity",
                    "cannot configure an access point");
        }

        ///////////////////
    }

1 个答案:

答案 0 :(得分:1)

我在你的代码中看到了一些错误。

第一部分是:

dispatch_queue_t mainQueue = dispatch_get_main_queue();

asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];

您正在主队列中运行连接,这不是一个好方法。因为在某种程度上,您可能会阻止主线程。或者主线程中的其他操作会阻止你。

我将做的是,我将连接放在主要的线程之外。

_asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];

第二部分是:

[sock writeData:requestData withTimeout:1 tag:1];

您只需将超时设置为1.这太短,至少将其设置为 30 ,或者只是将其设置为 -1 (我通常会这样做) ,没有超时。因为可能存在写入不成功的情况,所以连接不会再次重写数据,因为已达到超时。

您还可以通过此回调检查写入是否成功:

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag

如果你的iOS部分一切正常。然后我建议您检查Android部分的编码。