如何解决如何实现一个可以同时处理数据包的服务器?
所以我正在实现一个 android 服务器,我想同时接受多个数据包。
我的客户端应用程序是这样的:
#undef UNICODE
#include <stdio.h>
#include <winsock.h>
#include <ws2bth.h>
thread(n) {
SOCKET sock = socket(AF_BTH,SOCK_STREAM,BTHPROTO_RFCOMM);
/*some bthaddr*/
/*some refcom channel*/
SOCKADDR_BTH addrbth = { AF_BTH,0xFFFFFFFFFFFFFFFFULL,{0xFFFFFFFF,0xFFFF,{0xFF,0xFF,0xFF}},BT_PORT_ANY };
//setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(BOOL[1]) { 1 },sizeof (BOOL));
int res = connect(sock,&addrbth,sizeof addrbth);
printf("%d\n",WSAGetLastError());
const char strformat[] = "hello %d world!";
char str[sizeof strformat];
sprintf(str,strformat,n);
res = send(sock,str,strlen(str),0);
}
int main()
{
WSADATA wsadat; WSAStartup(MAKEWORD(2,2),&wsadat);
for (int i = 0; i < 10; ++i)
CreateThread(0,thread,i,0);
Sleep(INFINITE);
}
还有我的 Java 安卓应用:
package com.my.BluetoothMain;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.notificationmanager;
import android.bluetooth.*;
import static android.content.Context.*;
import android.content.*;
import static android.bluetooth.BluetoothProfile.*;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.media.ringtoneManager;
import android.os.ParcelUuid;
import android.widget.Toast;
import androidx.core.app.NotificationCompat;
import androidx.core.app.notificationmanagerCompat;
import static android.app.NotificationChannel.*;
public class BluetoothMain extends Thread
{
private static final UUID UUID_my_SERVER; //same as the client one
private Context ctx;
public BluetoothMain(Context ctx) {
this.ctx = ctx;
}
@Override
public void run() {try {
/*Set<BluetoothDevice> devices = manager.getAdapter().getBondedDevices();
for(BluetoothDevice dev : devices)
//dev.connectGatt(ctx,true,new GATTServer());
dev.*/
//BluetoothServerSocket servsock = manager.getAdapter().listenUsingRfcommWithServiceRecord("myServer",UUID_my_SERVER);
notificationmanager notificationmanager = (notificationmanager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
//notificationmanagerCompat notificationmanager = notificationmanagerCompat.from(ctx);
final String channelId = "my_channel_id";
NotificationChannel channel = new NotificationChannel(channelId,"my messages",notificationmanager.IMPORTANCE_HIGH);
channel.setShowBadge(true); // set false to disable badges,Oreo exclusive
assert notificationmanager != null;
notificationmanager.createNotificationChannel(channel);
int port = 1;
Constructor constructor = BluetoothSocket.class.getDeclaredConstructors()[0];
constructor.setAccessible(true);
Method bindlisten = BluetoothSocket.class.getDeclaredMethod("bindListen");
bindlisten.setAccessible(true);
Method accept = BluetoothSocket.class.getDeclaredMethod("accept",int.class);
accept.setAccessible(true);
class Inner implements Callable<Void>
{
private int port;
Inner(int portar) {
port = portar;
}
@Override
public Void call() { try {
//Method m = manager.getAdapter().getClass().getmethod("createInsecureRfcommSocket",new Class[] {int.class});
//new BluetoothSocket();
BluetoothManager manager = (BluetoothManager)ctx.getSystemService(BLUetoOTH_SERVICE);
BluetoothSocket servsock = (BluetoothSocket)constructor.newInstance(BluetoothSocket.TYPE_RFCOMM,-1,manager.getAdapter().getBondedDevices().iterator().next(),port,new ParcelUuid(UUID_my_SERVER));
//new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM,false,null,new ParcelUuid(UUID_my_SERVER));
//=BluetoothServerSocket servsock = manager.getAdapter().listenUsingRfcommWithServiceRecord("myServer",UUID_my_SERVER);
bindlisten.invoke(servsock);
BluetoothSocket sock = (BluetoothSocket)accept.invoke(servsock,-1);
servsock.close();
//BluetoothSocket sock = servsock.accept();
//new Inner().run();
InputStream instr = sock.getInputStream();
byte[] message = new byte[500];
//for(;;) {
int chsizemessage = instr.read(message);
String msg = new String(Arrays.copyOfRange(message,chsizemessage));
//Toast.makeText(ctx,new String(Arrays.copyOfRange(message,chsizemessage),StandardCharsets.UTF_8),Toast.LENGTH_LONG).show();
// the check ensures that the channel will only be made
// if the device is running Android 8+
Notification.Builder notification =
new Notification.Builder(ctx,channelId);
// the second parameter is the channel id.
// it should be the same as passed to the makeNotificationChannel() method
notification
.setSmallIcon(android.R.drawable.stat_sys_data_bluetooth) // can use any other icon
.setContentTitle("")
.setContentText(msg);
//.setNumber(3); // this shows a number in the notification dots
notificationmanager.cancel(1);
notificationmanager.notify(1,notification.build());
sock.close();
//new Inner(port).run();
} catch (Exception exc) {
System.out.println(exc.getCause());
System.out.println(exc.getStackTrace());
} return null;}
}
ExecutorService execs = Executors.newCachedThreadPool();
List<Callable<Void>> tasks = new ArrayList<Callable<Void>>();
for(int i = 0; i < 30; ++i)
tasks.add(new Inner(port++));
//instr.wait();
execs.invokeAll(tasks);
//}
} catch (Exception exc) {
System.out.println(exc.getCause());
System.out.println(exc.getStackTrace());
} }
}
如您所见,我正在尝试为 REFCOMM (1-30) 中的每个可用端口生成一个线程 - 但是我的客户端应用程序仅成功发送一条消息:
10048
10048
10048
10048
10048
0
10048
10048
10048
10048
我需要我的客户端代码相同并且不需要或具有隐式同步,但同时我的服务器(android)应该能够处理所有发送数据。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。