首页 \ 问答 \ 可靠的服务发现问题(issue with reliable service discovery)

可靠的服务发现问题(issue with reliable service discovery)

我在墙上敲我的头。 它有效,但它不起作用。

让我澄清一下,测试是在LG Optimus G,A Galaxy S4和联想平板电脑上运行4.1+

我在每个设备上启动一个服务器,每个设备在一个端口上自己广播,当用户点击发送时,所有已经解决了服务并且服务没有丢失的设备,一个线程将循环启动其他线程到连接到自己广播的服务器,并发送数据。 服务器接受传入连接,将其交给线程,然后重新打开。

所以回顾一下,每个设备都在广播服务器,每个设备都应该知道并跟踪其他服务器,当数据被发送时,所有已知的服务器都会受到攻击。

我的问题是,在2/3设备中,可以始终与设备的自身建立连接。

手机,但一次只有一个,似乎知道另一部手机,并能够连接到另一部手机。 即Galaxy S4可以向Optimus G打招呼,但是Optimus G除了自己或副歌之外不能说喜。

所以发现部分似乎不可靠,我不知道它是我,Android还是设备。 我需要外面的眼睛。 我试图以一种可以理解和深思熟虑的方式解决这个问题,我感谢任何对这个问题有所了解的人提供的任何帮助,因为我只是谦虚地开始进入网络世界,而且我更愿意向他们学习有人。

我需要一种更可靠的方式来跟踪服务或发现它们,因为我的实现至少看起来有缺陷。

我感谢任何先进的帮助。 (我不相信这是一个像大多数其他Android领域一样被踩踏的区域。)

这是初始化完成的地方。

/**initilize everything*/
private void buildNetwork()
{
    Log.d(TAG, "buildNetwork");
    networkHelper = new NetworkServiceDiscoveryHelper(this);
    networkHelper.initializeNsd(this);
    networkHelper.discoverServices();
    connectionReceiver = new ConnectionReceiver(this, this);
    // this next line launches the server thread which will obtain a socket
    // to be used in the finishBuildingNetwork()
    new Thread(connectionReceiver).start();

}

/** after the serversocket has been given a port we need to broadcast it*/
private void finishBuildingNetwork(int port)
{
    Log.d(TAG, "finishBuildingNetwork");
    networkHelper.registerService(port);
}

这是我对常见NSDManager助手类的一些改变。

public class NetworkServiceDiscoveryHelper
{

    public static final String TAG = "NetworkServiceDiscoveryHelper";
    public static final String KEY_DEVICE = "device";

    Context mContext;

    NsdManager mNsdManager;
    NsdManager.ResolveListener mResolveListener;
    NsdManager.DiscoveryListener mDiscoveryListener;
    NsdManager.RegistrationListener mRegistrationListener;

    public static final String SERVICE_TYPE = "_http._tcp.";

    public String mServiceName = "BlurbChat";

    NsdServiceInfo mService;

    private DiscoveredDevicesManager deviceManager;
    private NetworkDiscoveryHelperListener helperListener;

    /**
     * 
     * @param context
     *            - the activity context the service is to be attached to
     */
    public NetworkServiceDiscoveryHelper(Context context)
    {
        mContext = context;
        mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
        deviceManager = new DiscoveredDevicesManager();
    }

    /**
     * initialize the NetworkServiceDiscovery
     */
    public void initializeNsd(NetworkDiscoveryHelperListener helperListener)
    {
        this.helperListener = helperListener;

        initializeResolveListener();
        initializeDiscoveryListener();
        initializeRegistrationListener();

        // mNsdManager.init(mContext.getMainLooper(), this);

    }

    private void initializeDiscoveryListener()
    {
        mDiscoveryListener = new NsdManager.DiscoveryListener()
        {

            @Override
            public void onDiscoveryStarted(String regType)
            {
                Log.d(TAG, "Service discovery started");
                helperListener.SERVICE_STARTED(regType);
            }

            @Override
            public void onServiceFound(NsdServiceInfo service)
            {
                // A service was found! Do something with it.
                Log.d(TAG, "Service discovery success" + service);
                if (!service.getServiceType().equals(SERVICE_TYPE))
                {
                    // Service type is the string containing the protocol and
                    // transport layer for this service.
                    Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
                }
                else if (service.getServiceName().contains(mServiceName))
                {
                    // we have found our service! we use .contains because if
                    // there are multiple device with the same service being
                    // broadcast they will appear with name + (index)
                    // Resolve a discovered service. An application can resolve
                    // a service right before establishing a connection to fetch
                    // the IP and port details on which to setup the connection.
                    Log.d(TAG, "Found My Service Type: " + service.getServiceType() + service.getServiceName());
                    helperListener.SERVICE_FOUND(service);
                    mNsdManager.resolveService(service, mResolveListener);
                }

                /***************************************************************
                 * Checking the service name isn't always necessary, and is only relevant if you want to connect to a specific application.
                 * For instance, the application might only want to connect to instances of itself running on other devices. However, if the
                 * application wants to connect to a network printer, it's enough to see that the service type is "_ipp._tcp".
                 ******************************************************/
            }

            /**
             * when we lose our service
             */
            @Override
            public void onServiceLost(NsdServiceInfo service)
            {
                // When the network service is no longer available.
                Log.e(TAG, "service lost" + service);

                // remove the service
                if (deviceManager.removeDevice(service) != null)
                {
                    helperListener.SERVIVCE_LOST(service);
                }
            }

            /**
             * when our service is stopped
             */
            @Override
            public void onDiscoveryStopped(String serviceType)
            {
                Log.i(TAG, "Discovery stopped: " + serviceType);
                helperListener.DISCOVERY_STOPPED(serviceType);
            }

            @Override
            public void onStartDiscoveryFailed(String serviceType, int errorCode)
            {
                Log.e(TAG, "Discovery failed: Error code:" + errorCode);
                helperListener.DISCOVERY_START_FAILED(serviceType, errorCode);
                mNsdManager.stopServiceDiscovery(this);
            }

            @Override
            public void onStopDiscoveryFailed(String serviceType, int errorCode)
            {
                helperListener.DISCOVERY_STOP_FAILED(serviceType, errorCode);
                Log.e(TAG, "Discovery failed: Error code:" + errorCode);
                mNsdManager.stopServiceDiscovery(this);
            }
        };
    }

    private void initializeResolveListener()
    {
        mResolveListener = new NsdManager.ResolveListener()
        {

            @Override
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode)
            {
                // Called when the resolve fails. Use the error code to debug.
                Log.e(TAG, "Resolve failed" + errorCode);
                helperListener.RESOLVE_FAILED(serviceInfo, errorCode);
            }

            @Override
            public void onServiceResolved(NsdServiceInfo serviceInfo)
            {
                Log.e(TAG, "Resolve Succeeded. " + serviceInfo);

                if (serviceInfo.getServiceName().equals(mServiceName))
                {
                    Log.d(TAG, "Same IP.");
                    return;
                }

                mService = serviceInfo;
                DiscoveredDevice device = new DiscoveredDevice(mService.getPort(), mService.getHost(), mService.getServiceName(), mService.getServiceType());
                deviceManager.addDevice(device);
                helperListener.RESOLVE_SUCCESS(serviceInfo);
            }
        };
    }

    private void initializeRegistrationListener()
    {
        mRegistrationListener = new NsdManager.RegistrationListener()
        {

            @Override
            public void onServiceRegistered(NsdServiceInfo serviceInfo)
            {
                mServiceName = serviceInfo.getServiceName();
                helperListener.SERVICE_REGISTERED(serviceInfo);
            }

            @Override
            public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode)
            {
                helperListener.SERVICE_REGISTRATION_FAILED(serviceInfo, errorCode);
            }

            @Override
            public void onServiceUnregistered(NsdServiceInfo serviceInfo)
            {
                helperListener.SERVICE_UNREGISTERED(serviceInfo);
            }

            @Override
            public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode)
            {
                helperListener.SERVICE_UNREGISTRATION_FAILED(serviceInfo, errorCode);
            }

        };
    }

    /**
     * To be called after initialize()
     * 
     * @param port
     *            - the port you would like to register/broadcast the service through.
     */
    public void registerService(int port)
    {
        NsdServiceInfo serviceInfo = new NsdServiceInfo();
        serviceInfo.setPort(port);
        serviceInfo.setServiceName(mServiceName);
        serviceInfo.setServiceType(SERVICE_TYPE);

        mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);

    }

    /**
     * Initiate service discovery to browse for instances of a service type. Service discovery consumes network bandwidth and will continue
     * until the application calls stopServiceDiscovery(NsdManager.DiscoveryListener).
     */
    public void discoverServices()
    {
        mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
    }

    /**
     * Stop service discovery initiated with discoverServices(String, int, NsdManager.DiscoveryListener). An active service discovery is
     * notified to the application with onDiscoveryStarted(String) and it stays active until the application invokes a stop service
     * discovery. A successful stop is notified to with a call to onDiscoveryStopped(String).
     */
    public void stopDiscovery()
    {
        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
    }

    /**
     * 
     * @return - A class representing service information for network service discovery
     */
    public NsdServiceInfo getChosenServiceInfo()
    {
        return mService;
    }

    /**
     * Unregister a service registered through registerService(NsdServiceInfo, int, NsdManager.RegistrationListener). A successful
     * unregister is notified to the application with a call to onServiceUnregistered(NsdServiceInfo).
     */
    public void tearDown()
    {
        if (mNsdManager != null)
        {
            try
            {
                mNsdManager.unregisterService(mRegistrationListener);
                mNsdManager.stopServiceDiscovery(mDiscoveryListener);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    /**
     * 
     * @return - the DiscoveredDevicesManager that contains all valid devices which have the appropriate service susally will call this
     *         after a msg of RESOLVE_SUCCESS
     */
    public DiscoveredDevicesManager getDeviceManager()
    {
        return deviceManager;
    }

}

最后这是服务器的基础

    @Override
    public void run()
    {
        try
        {
            receiverSocket = new ServerSocket(0);

            onPortObtained(receiverSocket.getLocalPort());

            Log.d(TAG, "run");
            while (broadcastConnection)
            {
                try
                {
                    Socket newConnectionSocket = receiverSocket.accept();
                    onNewConnection(newConnectionSocket.getRemoteSocketAddress(), newConnectionSocket.getLocalSocketAddress());
                                    // to clarify this line launches a function that starts threads to handle the socket.
                    recieveConnection(newConnectionSocket);

                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        catch (IOException e1)
        {
            e1.printStackTrace();
        }
    }

编辑:还有一件事,有时在运行设备时会随机重启。 没有常见的事情导致,除此之外他们正在运行应用程序。


I am banging my head on the wall. It works, but it doesn't work.

Let me clarify, testing is on a LG Optimus G, A Galaxy S4, and a Lenovo Tablet all running 4.1+

I am launching a server on each device, each device is broadcasting itself on a port, and when the user hits send, all devices that have had their service resolved, and their service has not been lost, a thread will loop launching other threads to connect to the servers broadcasting themselves, and send the data. The servers accept the incoming connection, hand it off to a thread, and then re-open themselves.

So recap, every device has is broadcasting a server, every device is supposed to know and keep track of other servers, when data is sent all known servers get hit.

My issue is that in 2/3 devices connections can consistently be established with the device's self.

Either phone, but only 1 of them at a time, seems to know about the other phone and is able to connect to the other phone. i.e. Galaxy S4 can say hi to Optimus G, but Optimus G cannot say hi except only to itself, or vice-verse.

So the discovering portion seems unreliable, and I do not know if it is me, Android, or the devices. I need outside eyes. I have tried to lay this out in a understandable and thought out manner, and I appreciate any help from any one who has knowledge on this issue as I am just making humble beginnings into the world of networks, and am more then willing to learn from someone.

I need a more reliable way of keeping track of services, or discovering them, as my implementation at least seems flawed.

I thank any help in advanced. (I do not believe this is a area that is trodden as heavily as most other android areas.)

Here is where the initialization is done.

/**initilize everything*/
private void buildNetwork()
{
    Log.d(TAG, "buildNetwork");
    networkHelper = new NetworkServiceDiscoveryHelper(this);
    networkHelper.initializeNsd(this);
    networkHelper.discoverServices();
    connectionReceiver = new ConnectionReceiver(this, this);
    // this next line launches the server thread which will obtain a socket
    // to be used in the finishBuildingNetwork()
    new Thread(connectionReceiver).start();

}

/** after the serversocket has been given a port we need to broadcast it*/
private void finishBuildingNetwork(int port)
{
    Log.d(TAG, "finishBuildingNetwork");
    networkHelper.registerService(port);
}

This is my somewhat changed implementation of a common NSDManager helper class.

public class NetworkServiceDiscoveryHelper
{

    public static final String TAG = "NetworkServiceDiscoveryHelper";
    public static final String KEY_DEVICE = "device";

    Context mContext;

    NsdManager mNsdManager;
    NsdManager.ResolveListener mResolveListener;
    NsdManager.DiscoveryListener mDiscoveryListener;
    NsdManager.RegistrationListener mRegistrationListener;

    public static final String SERVICE_TYPE = "_http._tcp.";

    public String mServiceName = "BlurbChat";

    NsdServiceInfo mService;

    private DiscoveredDevicesManager deviceManager;
    private NetworkDiscoveryHelperListener helperListener;

    /**
     * 
     * @param context
     *            - the activity context the service is to be attached to
     */
    public NetworkServiceDiscoveryHelper(Context context)
    {
        mContext = context;
        mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
        deviceManager = new DiscoveredDevicesManager();
    }

    /**
     * initialize the NetworkServiceDiscovery
     */
    public void initializeNsd(NetworkDiscoveryHelperListener helperListener)
    {
        this.helperListener = helperListener;

        initializeResolveListener();
        initializeDiscoveryListener();
        initializeRegistrationListener();

        // mNsdManager.init(mContext.getMainLooper(), this);

    }

    private void initializeDiscoveryListener()
    {
        mDiscoveryListener = new NsdManager.DiscoveryListener()
        {

            @Override
            public void onDiscoveryStarted(String regType)
            {
                Log.d(TAG, "Service discovery started");
                helperListener.SERVICE_STARTED(regType);
            }

            @Override
            public void onServiceFound(NsdServiceInfo service)
            {
                // A service was found! Do something with it.
                Log.d(TAG, "Service discovery success" + service);
                if (!service.getServiceType().equals(SERVICE_TYPE))
                {
                    // Service type is the string containing the protocol and
                    // transport layer for this service.
                    Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
                }
                else if (service.getServiceName().contains(mServiceName))
                {
                    // we have found our service! we use .contains because if
                    // there are multiple device with the same service being
                    // broadcast they will appear with name + (index)
                    // Resolve a discovered service. An application can resolve
                    // a service right before establishing a connection to fetch
                    // the IP and port details on which to setup the connection.
                    Log.d(TAG, "Found My Service Type: " + service.getServiceType() + service.getServiceName());
                    helperListener.SERVICE_FOUND(service);
                    mNsdManager.resolveService(service, mResolveListener);
                }

                /***************************************************************
                 * Checking the service name isn't always necessary, and is only relevant if you want to connect to a specific application.
                 * For instance, the application might only want to connect to instances of itself running on other devices. However, if the
                 * application wants to connect to a network printer, it's enough to see that the service type is "_ipp._tcp".
                 ******************************************************/
            }

            /**
             * when we lose our service
             */
            @Override
            public void onServiceLost(NsdServiceInfo service)
            {
                // When the network service is no longer available.
                Log.e(TAG, "service lost" + service);

                // remove the service
                if (deviceManager.removeDevice(service) != null)
                {
                    helperListener.SERVIVCE_LOST(service);
                }
            }

            /**
             * when our service is stopped
             */
            @Override
            public void onDiscoveryStopped(String serviceType)
            {
                Log.i(TAG, "Discovery stopped: " + serviceType);
                helperListener.DISCOVERY_STOPPED(serviceType);
            }

            @Override
            public void onStartDiscoveryFailed(String serviceType, int errorCode)
            {
                Log.e(TAG, "Discovery failed: Error code:" + errorCode);
                helperListener.DISCOVERY_START_FAILED(serviceType, errorCode);
                mNsdManager.stopServiceDiscovery(this);
            }

            @Override
            public void onStopDiscoveryFailed(String serviceType, int errorCode)
            {
                helperListener.DISCOVERY_STOP_FAILED(serviceType, errorCode);
                Log.e(TAG, "Discovery failed: Error code:" + errorCode);
                mNsdManager.stopServiceDiscovery(this);
            }
        };
    }

    private void initializeResolveListener()
    {
        mResolveListener = new NsdManager.ResolveListener()
        {

            @Override
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode)
            {
                // Called when the resolve fails. Use the error code to debug.
                Log.e(TAG, "Resolve failed" + errorCode);
                helperListener.RESOLVE_FAILED(serviceInfo, errorCode);
            }

            @Override
            public void onServiceResolved(NsdServiceInfo serviceInfo)
            {
                Log.e(TAG, "Resolve Succeeded. " + serviceInfo);

                if (serviceInfo.getServiceName().equals(mServiceName))
                {
                    Log.d(TAG, "Same IP.");
                    return;
                }

                mService = serviceInfo;
                DiscoveredDevice device = new DiscoveredDevice(mService.getPort(), mService.getHost(), mService.getServiceName(), mService.getServiceType());
                deviceManager.addDevice(device);
                helperListener.RESOLVE_SUCCESS(serviceInfo);
            }
        };
    }

    private void initializeRegistrationListener()
    {
        mRegistrationListener = new NsdManager.RegistrationListener()
        {

            @Override
            public void onServiceRegistered(NsdServiceInfo serviceInfo)
            {
                mServiceName = serviceInfo.getServiceName();
                helperListener.SERVICE_REGISTERED(serviceInfo);
            }

            @Override
            public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode)
            {
                helperListener.SERVICE_REGISTRATION_FAILED(serviceInfo, errorCode);
            }

            @Override
            public void onServiceUnregistered(NsdServiceInfo serviceInfo)
            {
                helperListener.SERVICE_UNREGISTERED(serviceInfo);
            }

            @Override
            public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode)
            {
                helperListener.SERVICE_UNREGISTRATION_FAILED(serviceInfo, errorCode);
            }

        };
    }

    /**
     * To be called after initialize()
     * 
     * @param port
     *            - the port you would like to register/broadcast the service through.
     */
    public void registerService(int port)
    {
        NsdServiceInfo serviceInfo = new NsdServiceInfo();
        serviceInfo.setPort(port);
        serviceInfo.setServiceName(mServiceName);
        serviceInfo.setServiceType(SERVICE_TYPE);

        mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);

    }

    /**
     * Initiate service discovery to browse for instances of a service type. Service discovery consumes network bandwidth and will continue
     * until the application calls stopServiceDiscovery(NsdManager.DiscoveryListener).
     */
    public void discoverServices()
    {
        mNsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
    }

    /**
     * Stop service discovery initiated with discoverServices(String, int, NsdManager.DiscoveryListener). An active service discovery is
     * notified to the application with onDiscoveryStarted(String) and it stays active until the application invokes a stop service
     * discovery. A successful stop is notified to with a call to onDiscoveryStopped(String).
     */
    public void stopDiscovery()
    {
        mNsdManager.stopServiceDiscovery(mDiscoveryListener);
    }

    /**
     * 
     * @return - A class representing service information for network service discovery
     */
    public NsdServiceInfo getChosenServiceInfo()
    {
        return mService;
    }

    /**
     * Unregister a service registered through registerService(NsdServiceInfo, int, NsdManager.RegistrationListener). A successful
     * unregister is notified to the application with a call to onServiceUnregistered(NsdServiceInfo).
     */
    public void tearDown()
    {
        if (mNsdManager != null)
        {
            try
            {
                mNsdManager.unregisterService(mRegistrationListener);
                mNsdManager.stopServiceDiscovery(mDiscoveryListener);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    /**
     * 
     * @return - the DiscoveredDevicesManager that contains all valid devices which have the appropriate service susally will call this
     *         after a msg of RESOLVE_SUCCESS
     */
    public DiscoveredDevicesManager getDeviceManager()
    {
        return deviceManager;
    }

}

and finally this is the basis of the server

    @Override
    public void run()
    {
        try
        {
            receiverSocket = new ServerSocket(0);

            onPortObtained(receiverSocket.getLocalPort());

            Log.d(TAG, "run");
            while (broadcastConnection)
            {
                try
                {
                    Socket newConnectionSocket = receiverSocket.accept();
                    onNewConnection(newConnectionSocket.getRemoteSocketAddress(), newConnectionSocket.getLocalSocketAddress());
                                    // to clarify this line launches a function that starts threads to handle the socket.
                    recieveConnection(newConnectionSocket);

                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
        catch (IOException e1)
        {
            e1.printStackTrace();
        }
    }

Edit: one more thing, sometimes while running the devices will randomly restart. No common thing causing, other then they are running the app.


原文:https://stackoverflow.com/questions/16746375
更新时间:2023-08-17 17:08

最满意答案

您可以使用完成所有计数的GROUP BY,而无需以编程方式执行任何操作,请查看此查询:

select
  d.dt,
  count(*) as total
from
  (select distinct date(registered) dt from table1) d inner join
  table1 r on d.dt>=date(r.registered)
group by
  d.dt
order by
  d.dt

第一个子查询返回所有不同的日期,然后我们可以加入所有以前注册的所有日期,并在一个查询中进行计数。

可以在性能方面进行一些改进的替代连接条件是:

on d.dt + interval 1 day > r.registered

You can use a GROUP BY that does all the counts, without the need of doing anything programmatically, please have a look at this query:

select
  d.dt,
  count(*) as total
from
  (select distinct date(registered) dt from table1) d inner join
  table1 r on d.dt>=date(r.registered)
group by
  d.dt
order by
  d.dt

the first subquery returns all distinct dates, then we can join all dates with all previous registrations, and do the counts, all in one query.

An alternative join condition that can give some improvements in performance is:

on d.dt + interval 1 day > r.registered

相关问答

更多

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。