微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何实现一个可以同时处理数据包的服务器?

如何解决如何实现一个可以同时处理数据包的服务器?

所以我正在实现一个 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 举报,一经查实,本站将立刻删除。