如何在两个设备之间发送连续数据?

时间:2018-07-28 13:18:48

标签: android multithreading sockets android-asynctask serversocket

我有一个活动在服务器客户端之间建立连接。 在这种情况下,当我单击“连接” (按钮)时,它将消息从客户端发送到服务器,一切都很好!

现在,请注意,所有这些都是在一项活动之间发生的。单个应用(单个android文件)可同时处理服务器和客户端的代码。

因此显然存在多线程。没问题。 所以,这是代码:

package com.nitishprajapati.tcpsocket;

import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.view.animation.Animation;
import android.view.animation.AlphaAnimation;
import java.io.DataInputStream;
import java.lang.*;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import android.os.Handler;  
import java.net.Socket;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity{

    EditText ip,data;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView myText = (TextView) findViewById(R.id.myText);
        Animation anim = new AlphaAnimation(0.0f, 1.0f);
        data = (EditText) findViewById(R.id.editText);
        ip = (EditText) findViewById(R.id.ip);
        anim.setDuration(150); //You can manage the time of the blink with this parameter
        anim.setStartOffset(20);
        anim.setRepeatMode(Animation.REVERSE);
        anim.setRepeatCount(Animation.INFINITE);
        myText.startAnimation(anim);


        Thread myThread = new Thread(new MyServer());
        myThread.start();

    }


    class MyServer implements Runnable{
        ServerSocket ss;
        Socket mySocket;
        DataInputStream dis;
        String message;
        Handler handler = new Handler();

        @Override
        public void run(){

            try{
                ss = new ServerSocket(9700);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),"Waiting for client: ",Toast.LENGTH_SHORT).show();
                    }
                });
                while(true){
                    mySocket = ss.accept();
                    dis = new DataInputStream(mySocket.getInputStream());
                    message = dis.readUTF();
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),"message received from client: "+message, Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }catch (IOException excep){
                excep.printStackTrace();
            }
        }
    }




    public void button_click(View view){
        BackgroundTask b = new BackgroundTask();
        b.execute(ip.getText().toString(), data.getText().toString()); // all parameters should be of same type



        //            |  ¯\_(o_o)_/¯ not sure 
        //            |
        //            V

        //Intent intent = new Intent(this, PaintActivity.class);      
        //startActivity(intent);
    }

    class BackgroundTask extends AsyncTask<String/*TypeOfVarArgParams, perhaps from execute()*/,Void,String/*Result*/>
    {
        Socket s;
        DataOutputStream dos;
        String ip, message;

        @Override
        protected String doInBackground(String... strings/*from execute method i guess*/) {
            ip = strings[0];           // received from execute
            message = strings[1];      // received from execute
            try {
                s = new Socket(ip, 9700);
                dos = new DataOutputStream(s.getOutputStream());
                dos.writeUTF(message);

                dos.close();
            }catch (IOException excep){
                excep.printStackTrace();
            }
            return null;
        }
    }

}

enter image description here

赞: enter image description here

Toast显然出现在其I.P.已给出。

那么,现在让我感到困惑的是:为什么我需要将客户代码放入AsyncTask<>中?为什么不提供服务器代码? 为什么将服务器代码设为doInBackground(),而不是服务器代码?

但是,我的主要问题是: 当我单击“连接”时,现在它应该在客户端和服务器上都打开一个新的活动“ PaintActivity”,并且在客户端绘制时,我必须从客户端连续发送坐标。到服务器。因此,我将在哪里放置PaintActivity以及我该怎么做。背后的逻辑是什么?

这里是PaintActivity

package com.nitishprajapati.tcpsocket;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Path;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
import android.graphics.Color;


public class PaintActivity extends Activity {

    DrawingView dv ;
    private Paint mPaint;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Intent sendToLog =new Intent(getApplicationContext(),LoginActivity.class);
        //startActivity(sendToLog);
        dv = new DrawingView(this);
        dv.setBackgroundColor(Color.parseColor("#000000"));
        setContentView(dv);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(5);
    }

    public class DrawingView extends View {

        public int width;
        public  int height;
        private Bitmap mBitmap;
        private Canvas mCanvas;
        private Path mPath;
        private Paint   mBitmapPaint;
        Context context;
        private Paint circlePaint;
        private Path circlePath;

        public DrawingView(Context c) {
            super(c);
            context=c;                                      // Context
            mPath = new Path();                             // Path (mpath)
            mBitmapPaint = new Paint();                     // Paint
            mBitmapPaint.setDither(false);                  // Dither
            circlePaint = new Paint();                      // Paint
            circlePath = new Path();                        // Path (circle)
            circlePaint.setAntiAlias(true);                 // smoothening
            circlePaint.setColor(Color.GREEN);
            circlePaint.setStyle(Paint.Style.STROKE);
            circlePaint.setStrokeJoin(Paint.Join.MITER);
            circlePaint.setStrokeWidth(4f);
        }

        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);

            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);   // Bitmap
            mCanvas = new Canvas(mBitmap);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

            canvas.drawBitmap( mBitmap, 0, 0, mBitmapPaint);
            canvas.drawPath( mPath,  mPaint);
            canvas.drawPath( circlePath,  circlePaint);
        }

        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;

        private void touch_start(float x, float y) {
            mPath.reset();
            mPath.moveTo(x, y);
            mX = x;
            mY = y;
        }

        private void touch_move(float x, float y) {
            float dx = Math.abs(x - mX);
            float dy = Math.abs(y - mY);
            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
                mX = x;
                mY = y;

                circlePath.reset();
                circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
            }
        }

        private void touch_up() {
            mPath.lineTo(mX, mY);
            circlePath.reset();
            // commit the path to our offscreen
            mCanvas.drawPath(mPath,  mPaint);
            // kill this so we don't double draw
            mPath.reset();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    touch_start(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    touch_move(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    touch_up();
                    invalidate();
                    break;
            }
            return true;
        }
    }
}

那么,我该如何将两个部分链接在一起呢?

enter image description here

0 个答案:

没有答案