Android TCP客户端接收消息和bmp

时间:2016-09-03 17:27:58

标签: android string sockets tcp network-programming

我使用通用tcp客户端通过TCP接收字符串消息。 我希望收到特定消息后,例如" XXX"我的客户准备接收bmp图像。 我在C ++中的服务器发送消息但客户端没有收到图像...

经过一些建议......下面我修改了代码......

这是我的代码:

TCP客户端:

public class TCPClient {

private String serverMessage;
public static final String SERVERIP = "192.168.1.88"; //your computer IP
public static final int SERVERPORT = 80;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
private PrintWriter out;
private BufferedReader input;
private DataInputStream dis;
/**
 *  Constructor of the class. OnMessagedReceived listens for the messages received from server
 */
public TCPClient(OnMessageReceived listener) {
    mMessageListener = listener;
}

/**
 * Sends the message entered by client to the serveraddress
 * @param message text entered by client
 */
public void sendMessage(String message){
    if (out != null && !out.checkError()) {
        out.println(message);
        out.flush();
    }
}

public void stopClient(){

    mRun = false;
    if (out != null) {
        out.flush();
        out.close();
    }

    mMessageListener = null;
    input = null;
    input = null;
    input = null;
    serverMessage = null;
}

public void run() {

    mRun = true;
    try {
        //here you must put your computer's IP address.
        InetAddress serverAddr = InetAddress.getByName(SERVERIP);

        Log.e("TCP Client", "C: Connecting...");

        //create a socket to make the connection with the server
        Socket socket = new Socket(serverAddr, SERVERPORT);

        try {

            //send the message to the server
            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

            Log.e("TCP Client", "C: Sent.");

            Log.e("TCP Client", "C: Done.");

            //receive the message which the server sends back

            dis = new DataInputStream(socket.getInputStream());
            // The buffer reader cannot can't wrap an InputStream directly. It wraps another Reader.
            // So inputstreamreader is used.
            input = new BufferedReader(new InputStreamReader(dis, "UTF-8"));

            Log.d("MyApp","We are here");
            //this.input = new DataInputStream(in);

            //in this while the client listens for the messages sent by the server
            while (mRun) {
                Log.d("MyApp", "We are here 2");
                serverMessage = input.readLine();

                if (serverMessage != null && mMessageListener != null) {
                    //call the method messageReceived from MyActivity class
                    mMessageListener.messageReceived(serverMessage);

                    Log.d("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");
                }

                if ("XXX".equals(serverMessage)) {
                    Log.d("MyApp", "We are here 3");
                    serverMessage = null;
                    while (mRun) {
                        WriteSDCard writeSDCard = new WriteSDCard();

                        writeSDCard.writeToSDFile(serverMessage);


                        }
                    }
                }
              } finally {
                socket.close();
        }
            Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");

        } catch (Exception e) {

            Log.e("TCP", "S: Error", e);

        } finally {
            //the socket must be closed. It is not possible to reconnect to this socket
            // after it is closed, which means a new socket instance has to be created.

}

}

//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
    public void messageReceived(String message);
}
}
public class WriteSDCard extends Activity {

private static final String TAG = "MEDIA";
private TextView tv;



/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
//(not needed)        setContentView(R.layout.main);
//(not needed)           tv = (TextView) findViewById(R.id.TextView01);
    checkExternalMedia();
    String message =null;
  }


 /** Method to check whether external media available and writable. This is adapted from
 http://developer.android.com/guide/topics/data/data-storage.html#filesExternal */

private void checkExternalMedia(){
    boolean mExternalStorageAvailable = false;
    boolean mExternalStorageWriteable = false;
    String state = Environment.getExternalStorageState();

    if (Environment.MEDIA_MOUNTED.equals(state)) {
        // Can read and write the media
        mExternalStorageAvailable = mExternalStorageWriteable = true;
    } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        // Can only read the media
        mExternalStorageAvailable = true;
        mExternalStorageWriteable = false;
    } else {
        // Can't read or write
        mExternalStorageAvailable = mExternalStorageWriteable = false;
    }
    tv.append("\n\nExternal Media: readable="
            +mExternalStorageAvailable+" writable="+mExternalStorageWriteable);
}

  /** Method to write ascii text characters to file on SD card. Note that you must add a
   WRITE_EXTERNAL_STORAGE permission to the manifest file or this method will throw
 a FileNotFound Exception because you won't have write permission. */

   void writeToSDFile(String inputMsg){

    // Find the root of the external storage.
    // See http://developer.android.com/guide/topics/data/data-  storage.html#filesExternal

    File root = android.os.Environment.getExternalStorageDirectory();
    tv.append("\nExternal file system root: "+root);

    // See http://stackoverflow.com/questions/3551821/android-write-to-sd-card-folder

    File dir = new File (root.getAbsolutePath() + "/download");
    dir.mkdirs();
    Log.d("WriteSDCard", "Start writing");
    File file = new File(dir, "myData.txt");

    try {
        FileOutputStream f = new FileOutputStream(file);
        PrintWriter pw = new PrintWriter(f);
        pw.println(inputMsg);
        pw.flush();
        pw.close();
        f.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        Log.i(TAG, "******* File not found. Did you" +
                " add a WRITE_EXTERNAL_STORAGE permission to the   manifest?");
    } catch (IOException e) {
        e.printStackTrace();
    }
    tv.append("\n\nFile written to "+file);
}

/** Method to read in a text file placed in the res/raw directory of the application. The
 method reads in all lines of the file sequentially. */

}

服务器端:

代码:

void sendBMP( int cs, int xs, int ys)
{
int imgdataoffset = 14 + 40;     // file header size + bitmap header size
int rowsz = ((xs) + 3) & -4; // size of one padded row of pixels
int imgdatasize = (((xs*3) + 3) & -4) * ys;    // size of image data
int filesize = imgdataoffset + imgdatasize;
int i, y;



HTLM_bmp_H HTLM_bmp_h;
HTLM_bmp_h.bmfh.bfSize = filesize;
HTLM_bmp_h.bmfh.bfReserved1 = 0;
HTLM_bmp_h.bmfh.bfReserved2 = 0;
HTLM_bmp_h.bmfh.bfOffBits = imgdataoffset;

HTLM_bmp_h.bmih.biSize = 40;
HTLM_bmp_h.bmih.biWidth = xs;
HTLM_bmp_h.bmih.biHeight = ys;
HTLM_bmp_h.bmih.biPlanes = 1;
HTLM_bmp_h.bmih.biBitCount = 24;
HTLM_bmp_h.bmih.biCompression = 0;
HTLM_bmp_h.bmih.biSizeImage = imgdatasize;
HTLM_bmp_h.bmih.biXPelsPerMeter = 1000;
HTLM_bmp_h.bmih.biYPelsPerMeter = 1000;
HTLM_bmp_h.bmih.biClrUsed = 1 << 24;
HTLM_bmp_h.bmih.biClrImportant = 0;

printf("Start Sending BMP.\n"); 

send(cs,(unsigned char *)"BM",2,0);

send(cs,(unsigned char *)&HTLM_bmp_h,sizeof(HTLM_bmp_h),0);

printf("Sending...\n"); 

Buff_ptr = 0;

send(cs, (unsigned char *)Rbuffer, BUFF_SIZE,0 );
send(cs, (unsigned char *)Gbuffer, BUFF_SIZE,0 );
send(cs, (unsigned char *)Bbuffer, BUFF_SIZE,0 );
send(cs, (unsigned char *)"\n",1,0);        
send(cs, (unsigned char *)"END\n",4,0); 
printf("Done\n\n");
}

typedef struct {
//       char    bfType1;
//       char    bfType2;
int     bfSize;
short   bfReserved1;
short   bfReserved2;
int     bfOffBits;
} BMFH;


typedef struct {
unsigned int    biSize;
int    biWidth;
int    biHeight;
short    biPlanes;
short    biBitCount;
unsigned int    biCompression;
unsigned int    biSizeImage;
int    biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int    biClrUsed;
unsigned int    biClrImportant;
} BMIH;

typedef struct {
BMFH bmfh;
BMIH bmih;
} HTLM_bmp_H;

main()
{
TSK_Handle tsk_cam;
tsk_cam=TSK_create( (Fxn)TSK_webview, NULL);
TSK_setpri(tsk_cam, 8);
}

char buffer[2048];

Void TSK_webview()
{

int s,cs;
struct sockaddr_in    addr;    /* generic socket name */
struct sockaddr    client_addr;
int sock_len = sizeof(struct sockaddr);
int frame = 0;
LgUns i=0;
int len;
int x = DSKeye_SXGA_WIDTH, y = DSKeye_SXGA_HEIGHT;

DSKeye_params CAM_params = {
....
};


lwIP_NetStart();



/**************************************************************
    *     Main loop.
***************************************************************/

s = socket( AF_INET, SOCK_STREAM, 0 );

addr.sin_port = htons(80);
addr.sin_addr.s_addr = 0;
memset(&(addr.sin_zero), 0, sizeof(addr.sin_zero));
printf("start\n");
if( bind(s, (struct sockaddr*)&addr, sizeof(struct sockaddr)))
{
    printf("error binding to port\n");
    return ;
}
printf("xx1\n");
if(DSKeye_open(&CAM_params)) {
    printf("xx2\n");      
    SYS_abort("DSKcam_CAMopen");
printf("xx3\n");  fflush(stdout);}

printf("xx4\n");

while(1==1) {
    printf("Waiting for client to be connected ... \n");
    listen(s, 10);
    cs  = accept(s, &client_addr, &sock_len);
    printf("Client connected.\n");
    send(cs,(unsigned char *)"Server connected\n",17,0);
    recv(cs, (unsigned char*)buffer, 17, 0);


    switch (*(buffer)){
        case 'A' :
        ...
        case 'B' :
        ...
    }
    REG32(0xA0000080)=REG32(0xA0000080) - 0x800000; ///Disable stepper controller vhdl Quartus Block

    for(frame = 0; frame < 4; frame++){ // Allow AEC etc to settle

       SrcFrame=DSKeye_getFrame();
    }

    printf("Demosaicing of %d x %d image is ongoing \n", x, y);     
    demosaic(SrcFrame, x, y);       
    break;

}


    printf("Demosaicing completed ...\n");
    send(cs,(unsigned char *)"Demosaicing completed\n",22,0);   
    send(cs,(unsigned char *)"XXX\n",4,0);      
    sendBMP(cs, x, y);
    fflush(stdout);         
    lwip_close(cs); 

}

发送:lwip_send

int lwip_send(int s, void *data, int size, unsigned int flags)
{
  struct lwip_socket *sock;
  struct netbuf *buf;
  err_t err;

  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%d, flags=0x%x)\n", s, data, size, flags));

  sock = get_socket(s);
  if (!sock) {
    set_errno(EBADF);
    return -1;
  }

  switch (netconn_type(sock->conn)) {
  case NETCONN_RAW:
  case NETCONN_UDP:
  case NETCONN_UDPLITE:
  case NETCONN_UDPNOCHKSUM:
    /* create a buffer */
  buf = netbuf_new();

  if (!buf) {
     LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ENOBUFS\n", s));
      sock_set_errno(sock, ENOBUFS);
      return -1;
  }

  /* make the buffer point to the data that should
   be sent */
  netbuf_ref(buf, data, size);

  /* send the data */
  err = netconn_send(sock->conn, buf);

 /* deallocated the buffer */
 netbuf_delete(buf);
 break;
case NETCONN_TCP:
   err = netconn_write(sock->conn, data, size, NETCONN_COPY);
 break;
default:
  err = ERR_ARG;
  break;
 }
 if (err != ERR_OK) {
  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d\n", s, err));
  sock_set_errno(sock, err_to_errno(err));
  return -1;
 }

 LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) ok size=%d\n", s, size));
 sock_set_errno(sock, 0);
 return size;
  }

2 个答案:

答案 0 :(得分:1)

您不能在同一个套接字上混用缓冲读卡器和数据输入流。缓冲读取器将预读并窃取您希望通过数据输入流读取的数据。您将不得不使用数据输入流来处理所有事情。相应地在发件人处。

答案 1 :(得分:0)

您对字符串相等性进行了错误的比较。

在Java中,使用String.equals(Object anObject)

完成相等的字符串比较

您正在使用if (serverMessage == "XXX") {...

您应该使用if ("XXX".equals(serverMessage)) {...