Вопрос разработчикам Android-приложений (Socket Client)

Тема в разделе "Проводная и беспроводная связь", создана пользователем CryNET, 14 фев 2015.

  1. CryNET

    CryNET Гик

    Всем привет!

    Нужна помощь! Делаю некий проект, почти завершил. Осталась одна часть - андроид-приложение.
    Имею некий опыт в написании приложений, но с сокетами никогда не работал.

    Что я имею:
    1) Роутер TL-MR3020, на нем крутится WRT и ser2net, который слушает порт 1001/tcp
    2) Телефон с android
    3) Много энтузиазма и времени.

    Проверил работу ser2net через виртуальный СОМ порт, через ArduinoIDE слал в него данные, ответ получал. Т.е со стороны роутера-сервера все хорошо, там проблем нету.
    Так же скачал TCP-client с playmarket'a, через него посылал и получал данные.
    Следовательно аппаратно все работает и осталось только разобраться как написать приложение.

    Готовое приложение с маркета не нужно, т.к мне нужно его переделать под свои нужды.
    В инете находил 2-3 примера, но чистый копи-паст не true, тем более чисто скопированный код не работает. Если было бы по-больше знаний, быть может, смог бы его переделать.

    Заранее спасибо!

    P.S. И желательно чтобы были минимальные объяснения, чтобы я смог понять зачем оно надо ;)
     
  2. root

    root Нуб

    http://android-er.blogspot.com/2014/02/android-sercerclient-example-client.html
    Вот тебе отличный пример.
    Но! бери во внимание то что если андройд подключен к сети через роутер(wifi) самостоятельно он будет работать только на базовых портах 80, 443 и т.д. Если тебе нужно что бы работало везде лучше юзать их, в противном случаи придется настраивать роут-таблицы на wifiРоутерах что бы пакеты нормально доходили.

    По сути сокет это очень простая штука, соотношение Ip+port=socket. Ip нужен для навигации пакета внутри интернета, порт нужен для навигации пакета внутри компа(мобилки). В выше указанной статье все по коду поймешь общая суть .
    Псевдокодом.

    Socket sock=new Socket(2211); // создаем сокет на порту 2211
    sock.open(); // открываем

    while(sock.isOpen()){ // крутим цикл пока сокет открыт
    if(sock.read()){ // если есть что читать читаем
    byte[] requestArray= sock.readAllByte();
    System.out.print("request: "+new String(requestArray)); //выводим что пришло в случаи если слали текст
    }
    }
     
    CryNET нравится это.
  3. CryNET

    CryNET Гик

    Я разобрался с сокетами, долго мусолить не буду, а просто оставлю тут код.
    Долго парился, в инете не мог найти 100% рабочие исходники, допер сам. Код не идеален, но рабочий.

    AndroidManifest.xml
    HTML:
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.sibear.tcpc" >
        <uses-permission android:name="android.permission.INTERNET" />
        <application
           android:allowBackup="true"
           android:icon="@drawable/ic_launcher"
           android:label="@string/app_name"
           android:theme="@style/AppTheme" >
            <activity
               android:name=".MainActivity"
               android:label="@string/app_name"
               android:screenOrientation="portrait" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>

    </manifest>
    MainActivity.java
    Код (Text):
    package com.sibear.tcpc;

    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;

    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.InetAddress;
    import java.net.Socket;

    public class MainActivity extends Activity
    {
        public static String SERVERIP = "192.168.0.7"; //your computer IP address
        public static int SERVERPORT = 7777;
        String message;
        String bufer;
        PrintWriter out;

        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            final EditText editText = (EditText) findViewById(R.id.editText);
            Button send = (Button) findViewById(R.id.btn);
            final Button conn = (Button) findViewById(R.id.cnbtn);
            final EditText ips = (EditText) findViewById(R.id.ipstr);
            final EditText ports = (EditText) findViewById(R.id.portstr);

            conn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    SERVERIP = ips.getText().toString();
                    SERVERPORT = Integer.parseInt(ports.getText().toString());
                    conn.setEnabled(false);
                    mThr.start();
                }
            });

            //mThr.start();

            send.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    message = editText.getText().toString();
                    Log.e("TCP Client", "Send Button");
                }
            });
        }
        Thread mThr = new Thread(new Runnable() {
            @Override
            public void run() {
                InetAddress serverAddr;
                Socket socket = null;
                Log.e("TCP Client", "C: Connecting...");
                while(true){
                        if(bufer == message){

                        }
                        else{
                            try{
                                serverAddr = InetAddress.getByName(SERVERIP);
                                socket = new Socket(serverAddr, SERVERPORT);
                                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                                out.println(message);
                                out.flush();
                                bufer = message;
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            try{
                                assert socket != null;
                                socket.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                }

            }
        });
    }
    activity_main.xml
    HTML:
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

        <EditText
           android:layout_width="245dp"
           android:layout_height="wrap_content"
           android:id="@+id/editText"
           android:text="@string/starttxt"
           android:minWidth="100dp"
           android:inputType="text"
           android:layout_above="@+id/btn"
           android:layout_alignRight="@+id/btn"
           android:layout_alignEnd="@+id/btn" />

        <Button
           android:layout_width="156dp"
           android:layout_height="wrap_content"
           android:text="@string/sendstr"
           android:id="@+id/btn"
           android:layout_gravity="center_horizontal"
           android:minHeight="71dp"
           android:minWidth="400dp"
           android:layout_marginBottom="51dp"
           android:layout_alignParentBottom="true"
           android:layout_centerHorizontal="true" />

        <EditText
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:id="@+id/ipstr"
           android:inputType="phone"
           android:layout_alignParentTop="true"
           android:layout_alignLeft="@+id/editText"
           android:layout_alignStart="@+id/editText"
           android:layout_marginTop="60dp"
           android:text="@string/ipstring"
           android:minWidth="156dp" />

        <EditText
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:inputType="phone"
           android:ems="10"
           android:id="@+id/portstr"
           android:text="@string/portstr"
           android:layout_marginTop="10dp"
           android:layout_below="@+id/ipstr"
           android:layout_alignLeft="@+id/ipstr"
           android:layout_alignStart="@+id/ipstr"
           android:minWidth="156dp"
           android:maxWidth="156dp"
           android:layout_alignRight="@+id/ipstr"
           android:layout_alignEnd="@+id/ipstr" />

        <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:textAppearance="?android:attr/textAppearanceSmall"
           android:text="@string/striptxt"
           android:id="@+id/textView"
           android:layout_above="@+id/portstr"
           android:layout_alignRight="@+id/editText"
           android:layout_alignEnd="@+id/editText" />

        <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:textAppearance="?android:attr/textAppearanceSmall"
           android:text="@string/strporttxt"
           android:id="@+id/textView2"
           android:layout_alignBottom="@+id/portstr"
           android:layout_alignLeft="@+id/textView"
           android:layout_alignStart="@+id/textView" />

        <Button
           style="?android:attr/buttonStyleSmall"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@string/strcontxt"
           android:id="@+id/cnbtn"
           android:layout_below="@+id/portstr"
           android:layout_alignLeft="@+id/portstr"
           android:layout_alignStart="@+id/portstr"
           android:minWidth="70dp" />

    </RelativeLayout>
    Немного помогла эта статья
    Делалось на Android Studio, последняя версия на сегодняшний день.

    UPD:
    Для проверки накидал сервер TCP на Python:

    Код (Text):
    import SocketServer

    class MyTCPHandler(SocketServer.BaseRequestHandler):
        """
        The RequestHandler class for our server.

        It is instantiated once per connection to the server, and must
        override the handle() method to implement communication to the
        client.
        """

        def handle(self):
            # self.request is the TCP socket connected to the client
            self.data = self.request.recv(1024).strip()
            print "{} wrote:".format(self.client_address[0])
            print self.data
            # just send back the same data, but upper-cased
            self.request.sendall(self.data.upper())

    if __name__ == "__main__":
        HOST, PORT = "192.168.0.7", 7777

        # Create the server, binding to localhost on port 9999
        server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)

        # Activate the server; this will keep running until you
        # interrupt the program with Ctrl-C
        server.serve_forever()
     
  4. CryNET

    CryNET Гик

    P.S.
    Почему бы в вашу wiki не добавить статью про общение Arduino и Android по интернету/вафле, ведь по Bluetooth уже есть? Наброски кода уже есть ;)