我正在开发一个需要从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");
}
///////////////////
}
答案 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部分的编码。