0

これが非常に一般的な質問である場合は申し訳ありませんが、どこから始めればよいかわからないので、アイデアを探しています。

私は Windows アプリ (楽譜編集) を持っており、現在、順調に進んでいる Android に移植しています。

Windows アプリで作成したドキュメントをユーザーの Android タブレットに送信できる機能を追加したいと考えています。両方が同じローカルネットワーク上にあると仮定して、Windows側がソケットまたは何かを開いてデータを送信できるように、Androidである種のリスナーをどのように作成するのか疑問に思っていました。

ありがとう

4

2 に答える 2

0

私のWindowsアプリがローカルネットワーク上で実行されている私のAndroidアプリのインスタンスを見つけることができるように、私は小さなことを書きました. これは最初のAndroidコードです

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;

import android.os.AsyncTask;
import android.util.Log;

public class TabSyncServer extends AsyncTask<Void, Void, Void> {

    ServerSocket mServerSocket = null;
    Socket mSocket = null;
    DataInputStream mDataInputStream = null;
    DataOutputStream mDataOutputStream = null;

    @Override
    protected void onPreExecute() {

        try {
            mServerSocket = new ServerSocket(2112);
            //System.out.println("Listening :2112");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    protected Void doInBackground(Void... args) {
        byte[] bytebuf = new byte[1024];
        while (true) {
            try {

                mSocket = mServerSocket.accept();
                mDataInputStream = new DataInputStream(mSocket.getInputStream());
                mDataOutputStream = new DataOutputStream(mSocket.getOutputStream());
                Log.d("TabSyncServer", "ip: " + mSocket.getInetAddress());
                mDataInputStream.read(bytebuf);

                String str = new String(bytebuf, "UTF8");
                Log.d("TabSyncServer", "message: " + str);
                if(str.contains("Hello Android")) {
                    Log.d("TabSyncServer", "sending reply");
                    mDataOutputStream.writeBytes("Hello Windows");
                }

                // 

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (mSocket != null) {
                    try {
                        mSocket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

                if (mDataInputStream != null) {
                    try {
                        mDataInputStream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

                if (mDataOutputStream != null) {
                    try {
                        mDataOutputStream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }

    }

}

およびWindows MFCコード

    void CMainFrame::OnBrowseMobile() {


    CMobileSync* con = new CMobileSync();
    CString ipaddr_base;
    int my_last_digit;
    if(!con->getMyIP(ipaddr_base, my_last_digit)) {
        setMobilePath("Can't find local network");
        return;
    }


    for(int i=1 ; i<98 ; i++) {
        if(i==my_last_digit)
            continue;       // don;t check self

        CString ipaddr; ipaddr.Format("%s.%d", ipaddr_base, i);
        bool res = con->ConnectToHost(ipaddr);
        if(res) {
            res = con->SendMsg ("Hello Android");

            if(res) {
                TRACE1("send ok %s\n",ipaddr.GetBuffer());
#define RD_BUF_LEN 80
                char buffer[RD_BUF_LEN];
                if(con->ListenOnPortBlocking(buffer, RD_BUF_LEN)) {
                    if(strncmp(buffer, "Hello Windows", 12)==0) {
                        TRACE1("reply ok %s", buffer);
                        setMobilePath(ipaddr);
                        con->CloseConnection ();
                        return;
                    }
                }
            } else {
                TRACE("send FAILED\n");
            }
        }
        con->CloseConnection ();
    }
    setMobilePath("No TabTrax on local network");
}

#include "stdafx.h"
#include <winsock.h>
#include "MobileSync.h"

#define TTPORT 2112
bool CMobileSync::getMyIP(CString& ipaddr_front, int& ipaddr_lastdigit)
{
    char szBuffer[1024];

    #ifdef WIN32
    WSADATA wsaData;
    WORD wVersionRequested = MAKEWORD(2, 0);
    if(::WSAStartup(wVersionRequested, &wsaData) != 0)
        return false;
    #endif


    if(gethostname(szBuffer, sizeof(szBuffer)) == SOCKET_ERROR)
    {
      #ifdef WIN32
      WSACleanup();
      #endif
      return false;
    }

    struct hostent *host = gethostbyname(szBuffer);
    if(host == NULL)
    {
      #ifdef WIN32
      WSACleanup();
      #endif
      return false;
    }

    //Obtain the computer's IP
    unsigned char b1, b2, b3, b4;
    b1 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b1;
    b2 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b2;
    b3 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b3;
    b4 = ((struct in_addr *)(host->h_addr))->S_un.S_un_b.s_b4;

    ipaddr_front.Format("%d.%d.%d", b1, b2, b3);
    ipaddr_lastdigit = b4;
    #ifdef WIN32
    WSACleanup();
    #endif
    return true;
}

//CONNECTTOHOST – Connects to a remote host
bool CMobileSync::ConnectToHost(const char* IPAddress)
{
    //Start up Winsock…
    WSADATA wsadata;

    int error = WSAStartup(0x0202, &wsadata);

    //Did something happen?
    if (error)
        return false;

    //Did we get the right Winsock version?
    if (wsadata.wVersion != 0x0202)
    {
        WSACleanup(); //Clean up Winsock
        return false;
    }

    //Fill out the information needed to initialize a socket…
    SOCKADDR_IN target; //Socket address information

    target.sin_family = AF_INET; // address family Internet
    target.sin_port = htons (TTPORT); //Port to connect on
    target.sin_addr.s_addr = inet_addr (IPAddress); //Target IP

    mSocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create socket
    if (mSocket == INVALID_SOCKET)
    {
        return false; //Couldn't create the socket
    }  

    //Try connecting...

    if (connect(mSocket, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR)
    {
        return false; //Couldn't connect
    }

    return true; //Success
}

//CLOSECONNECTION – shuts down the socket and closes any connection on it
void CMobileSync::CloseConnection ()
{
    //Close the socket if it exists
    if (mSocket)
        closesocket(mSocket);
    mSocket=0;

    WSACleanup(); //Clean up Winsock
}

int CMobileSync::SendMsg (char* szpText, int buflen)
{
    if(buflen==0)
        buflen = strlen(szpText);
    int ret = send(mSocket, szpText, buflen, 0);
    TRACE1("CMobileSync::SendMsg sent %d bytes\n", ret);
    return ret;
}

WSADATA w;

//LISTENONPORT – Listens on a specified port for incoming connections 
//or data
bool CMobileSync::ListenOnPortBlocking(char* buffer, int buflen)
{
    //Now we can start listening (allowing as many connections as possible to  
    //be made at the same time using SOMAXCONN). You could specify any 
    //integer value equal to or lesser than SOMAXCONN instead for custom 
    //purposes). The function will not //return until a connection request is 
    //made
    // listen(s, SOMAXCONN);

    memset(buffer, 0, sizeof(buffer)); //Clear the buffer

    int iTimeout = 1600;
    setsockopt( mSocket,  SOL_SOCKET, SO_RCVTIMEO, (const char *)&iTimeout, sizeof(iTimeout));

    //Put the incoming text into our buffer
    int ret = recv (mSocket, buffer, buflen-1, 0); 

    //Don't forget to clean up with CloseConnection()!

    if(ret != SOCKET_ERROR)
        return true;

    int err = WSAGetLastError();
    return false;
}

広範囲にテストされていませんが、実行されています

これは誰かに役立つかもしれません

于 2013-02-18T06:25:29.517 に答える
0

ローカル ネットワーク経由でファイルを直接送信するのは、最善の方法ではないと思います。共有が機能していないという多くのユーザーの苦情が発生する傾向があります..これは主に、ユーザー自身のネットワーク構成の問題が原因です.

DropBox のようなサービスを使用してファイル共有を実装してみませんか?

DropBox などのサービスは、ファイルをリモート フォルダーに保存したり、リモート フォルダーからファイルを読み取ったりするためにアプリで使用できるシンプルな API を提供します。

このように、ユーザーはまったく同じネットワークにいる必要はありません..そして、ファイル共有を実装するための重労働のほとんどは、それに焦点を当てたサービスによって行われます.

添加:

DropBox のような別のサービスにアカウントを要求したくない場合は、次のアプローチを検討してください。 非常に単純な DropBox のようなサービスを独自の Web サーバーに実装します。ユーザーが HTTP 経由で匿名でサーバーにファイルをアップロードできるようにする簡単なスクリプトを作成します。アップロード後、このファイルの 5 桁の ID、または共有できる他のリンクを受け取ります。2 番目のアプリからこの ID またはリンクを使用すると、ファイルをダウンロードできます (これも HTTP 経由)。数時間後にサーバーからファイルを自動的に削除すると、スペースが不足することはありません。

このようなサービスは、約 20 行の PHP コードで実装できます。また、必要なアプリ コードは非常に単純です (HTTP のみに依存しているため)。Web サーバーのコストが心配な場合は、月額約 5 ドルから入手するか、Google App Engine などの無料サービスを使用することもできます (帯域幅とスペースの要件が低い場合は無料です)。

ファイルアップロードのコード例。ダウンロードは、一人でできるほど簡単でなければなりません。定期的なファイルの削除については、cronを使うのが当たり前ですが、なくても管理しやすいと思います。(PHP スクリプトで) 新しいアップロードを受け入れるときはいつでも、すべてのダウンロードを確認し、古いものを削除します。

于 2013-02-17T15:32:49.927 に答える