如何从服务器向客户端发送消息(TCP,android应用程序) [英] How to send message from server to client (TCP , android applications)

查看:93
本文介绍了如何从服务器向客户端发送消息(TCP,android应用程序)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了两个与套接字连接的android应用程序。客户端将图像发送到服务器,服务器显示它。当你触摸服务器上的图像时,它会得到它的坐标,现在正在运行。我需要的是服务器将坐标发送到客户端,但我不知道如何将它们发送到客户端并检索它们,我应该打开一个新的套接字吗?我不知道该怎么做。请问有人帮我吗?



这是我的代码到目前为止



I had created two android applications connected with sockets. Client sends an image to server and Server displays it. when you touch the image on server, it gets its coordinates,this is working now. what I need is that server sends the coordinates to the client, but I dont know how to send them to client and retrieve them, should I open a new socket ? I have no idea how to do this. Can somebody give me a hand please?

This is my code so far

///////////////////////////SERVER/////////////////////
package com.example.serverlate;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.widget.ImageView;
import android.widget.TextView;

public class ServerLate extends Activity {

    private ServerSocket serverSocket;
    String touchedCoordinates;
    Handler updateConversationHandler;
    Thread serverThread = null;
    private ImageView imageView;
    public static final int SERVERPORT = 6000;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_server_late);

        imageView=(ImageView) findViewById(R.id.imageViewServer);

        updateConversationHandler = new Handler();
        this.serverThread = new Thread(new ServerThread());
        this.serverThread.start();

    }

    @Override
    protected void onStop() {
        super.onStop();
        try {
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class ServerThread implements Runnable {

        public void run() {
            Socket socket = null;
            try {
                serverSocket = new ServerSocket(SERVERPORT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            while (!Thread.currentThread().isInterrupted()) {

                try {

                    socket = serverSocket.accept();
                    CommunicationThread commThread = new CommunicationThread(socket);
                    new Thread(commThread).start();

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

    class CommunicationThread implements Runnable {

        private Socket clientSocket;
        private DataInputStream input;    
        public CommunicationThread(Socket clientSocket) {

            this.clientSocket = clientSocket;

            try {
                InputStream in = this.clientSocket.getInputStream();
                this.input = new DataInputStream(in);               
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void run() {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    byte[] data;
                    int len= this.input.readInt();                  
                    data = new byte[len];                   
                    if (len > 0) {
                        this.input.readFully(data,0,data.length);
                    }   
                    updateConversationHandler.post(new updateUIThread(data));
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

    class updateUIThread implements Runnable {
        private byte[] byteArray;

        public updateUIThread(byte[] array){    
            this.byteArray=array;   
        }

        @Override
        public void run() { 
            Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray , 0, byteArray .length);
            imageView.setImageBitmap(bitmap);
            imageView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                touchedCoordinates="Touch coordinates : " +
                        String.valueOf(event.getX()) + " x " + String.valueOf(event.getY());
                    return true;
            }
        });
        }
    }
}







/////////////////////CLIENT///////////////////////////////
package com.example.clientlate;

import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;

public class ClientLate extends Activity {

    private Socket socket;

    private static final int SERVERPORT = 5000;
    private static final String SERVER_IP = "10.0.2.2";

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

        new Thread(new ClientThread()).start();
    }

    public void onClick(View view) {
        try {           
            ImageView imageView=(ImageView) findViewById(R.id.imageView1);
            Bitmap bmp=((BitmapDrawable)imageView.getDrawable()).getBitmap(); 

            ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
            bmp.compress(CompressFormat.PNG, 0 /*ignored for PNG*/, bos); 
            byte[] array = bos.toByteArray();

            OutputStream out = socket.getOutputStream(); 
            DataOutputStream dos = new DataOutputStream(out);
            dos.writeInt(array.length);
            dos.write(array, 0, array.length);

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    class ClientThread implements Runnable {

        @Override
        public void run() {

            try {
                InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

                socket = new Socket(serverAddr, SERVERPORT);

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

        }

    }
}





推荐答案

使用TCP,发送数据的方式完全没有区别:从客户端到服务器或从服务器到客户端。连接始终由客户端的主动建立,该客户端连接到侦听服务器,这是客户端是客户端而服务器是服务器的唯一原因。连接后,客户端和服务器部分可以在两个方向上交换数据,只有这些操作的顺序应该匹配,这是由您在TCP上使用的一个或另一个应用层协议建立的(这是传输级协议:

http://en.wikipedia.org/ wiki / Application_layer [ ^ ],

http://en.wikipedia.org/wiki/Transport_layer [ ^ ],

http://en.wikipedia.org/wiki/Transmission_Control_Protocol [ ^ ]。



我想强调一下这样的应用层协议总是存在,即使你认为你没有;在这种情况下,此类协议仍然存在,由您的代码隐式定义。当然,承认它的存在并更明确地定义它会更有成效。现在,有些人可能认为这样的协议工作如下:客户端连接,发送一个或多个请求;并且服务器端响应每个请求。即使在许多情况下就像HTML这样的情况,这绝对不是一个法律。您的协议可以是其他任何内容。



此外,您可以在同一客户端和同一服务之间拥有两个不同的TCP会话。服务器可以侦听两个端口,每个客户端可以连接并建立两个单独的连接。对于一对套接字(客户端和服务器套接字),协议可以允许客户端发送请求,服务器应该响应;在第二个,服务器始终请求,客户端响应。在第一个客户端请求时,客户端可以向服务器传递某种标识,因此服务器可以在两个客户端套接字之间创建关联,作为同一逻辑客户端的套接字。这只是一个非常简单的操作示例。实际上,你只会受到两件事的限制:1)TCP协议,2)你的幻想。



对于更多想法,请看看我过去的答案(与TCP相关但与Java和Android无关):

套接字编程中的业余问题 [ ^ ],
来自同一端口号码的多个客户端 [ ^ ]。



祝你好运,

-SA
With TCP, there is absolutely no difference where how sending data is directed: from client to server or from server to client. The connection is always established by the initiative of the client, which is connected to the listening server, and this is the only reason why a client is a client and a server is a server. After connection, client and server part can exchange data in both directions, only the order of these operations should be matching, which is established by one or another application-layer protocol you use over TCP (which is the transport-level protocol:
http://en.wikipedia.org/wiki/Application_layer[^],
http://en.wikipedia.org/wiki/Transport_layer[^],
http://en.wikipedia.org/wiki/Transmission_Control_Protocol[^].

I want to emphasize that such application-layer protocol always exist, even if you think you don't have any; in this case, such protocol still exist, implicitly defined by your code. Naturally, it's more productive to admit its existence and define it more explicitly. Now, some may think that such protocol works as follows: the client connects, sends one or more requests; and the server side responds to each request. Even though this is the case in many cases, like HTML, this is absolutely not a law. Your protocol can be anything else.

Besides, you can have two different TCP sessions between the same client and the same service. A server can listen on two ports, and each client can connect and establish two separate connections. For one pair of sockets (client and server sockets), the protocol can allow a client to send requests and the server should respond; on second on, the server always requests and the client responds. At the first client request, the client can pass the server some kind of identification, so the server could create an association between two client sockets, as the sockets "of the same logical client". This is just a very simple example of the operations. In reality, you will be limited only by two things 1) TCP protocol, 2) your fantasy.

For some more ideas, please take a look at my past answers (related to TCP but unrelated to Java and Android):
an amateur question in socket programming[^],
Multple clients from same port Number[^].

Good luck,
—SA


你可以使用Google Cloud Messaging for Android



http://developer.android.com/google/gcm/index.html [ ^ ]



< a href =http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/> http://www.androidhive。 info / 2012/10 / android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql / [ ^ ]
You can use Google Cloud Messaging for Android

http://developer.android.com/google/gcm/index.html[^]

http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/[^]

这篇关于如何从服务器向客户端发送消息(TCP,android应用程序)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆