TCP客户端到服务器通信不符合预期

时间:2017-05-23 11:59:42

标签: java android python c sockets

我正在尝试创建一个为每个特定按钮发送一个字节的控制器。

为了进行测试,我在Python中创建了一个客户端以及C中的服务器。结果如预期的那样,如果我按下按钮它会发送0x1例如,直到我释放按钮,因为它然后发送另一个字节告诉服务器我发布了按钮(0x2)。服务器收到这个罚款。

现在我正在尝试用Java做同样的事情,更具体的是Android。当我按下Android应用程序中的按钮时,它发送0x1,服务器接收到该消息,但在释放按钮后,服务器仅在断开客户端后才接收0x2字节。

当然,我想要与在Python中使用我的客户端时相同的结果。

Python中的客户端:

class MainWindow(QWidget, Ui_Form):
    def __init__(self, TCP_IP, TCP_PORT):
        super(MainWindow, self).__init__()
        """ TCP related """
        self.TCP_IP = TCP_IP
        self.TCP_PORT = TCP_PORT
        self.sock = None

        """ Ui related """
        self.setupUi(self)
        self.setWindowTitle("RC Car Controller")
        self.setWindowIcon(QIcon("6269-200.png"))

        """ Initialize the socket """
        self.initialize_socket()

    def initialize_socket(self):
        try:
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # TCP
            self.sock.connect((self.TCP_IP, self.TCP_PORT))

        except Exception as e:
            print(e)

    @pyqtSlot(name="")
    def on_btnFullForward_pressed(self):
        self.send_data(b'\x01')

    @pyqtSlot(name="")
    def on_btnFullForward_released(self):
        self.send_data(b'\x02')

    def send_data(self, data):
        try:
            self.sock.send(data)
        except Exception as e:
            print(e)

我在C中的服务器示例:

unsigned char buffer[1];
struct sockaddr_in serverAddr, clientAddr;
int tcpSocket, slen, n, conn;

void ConnectionSocket(char* ip){

    /*Create TCP socket*/
    tcpSocket = socket(AF_INET, SOCK_STREAM, 0);

    if (tcpSocket < 0) {
        perror("ERROR opening socket");
        exit(1);
    }

    memset(&serverAddr, '0', sizeof(serverAddr));
    memset(buffer, '0', sizeof(buffer));

    /*Configure settings in address struct*/
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(7891);
    serverAddr.sin_addr.s_addr = inet_addr(ip);

    if (bind(tcpSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) < 0) {
        perror("ERROR on binding");
    }

    if(listen(tcpSocket, 10) == -1){
        printf("Failed to listen\n");
    }

    slen = sizeof(clientAddr);
    conn = accept(tcpSocket,(struct sockaddr *)&clientAddr, &slen); // Blocking!
}

void loop(){
    while(1){
        if (conn < 0) {
            perror("ERROR on accept");
            exit(1);
        }

        n = read(conn, buffer, 1);

        if (n == NULL){
            printf("Client has disconnected!, Trying to reconnect..\n");
            emergency_stop();
            reconnect_on_failed();
        }else{
            printf("Received packet from %s:%d\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
            control_car(buffer);
            handle_pins();
        }
    }
}

void reconnect_on_failed(){
    slen = sizeof(clientAddr);
    conn = accept(tcpSocket,(struct sockaddr *)&clientAddr, &slen); // Blocking!
    printf("Client has reconnected!\n");
}

Java(Android)客户端:

package com.example.gianni.rccar;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MotionEvent;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;


public class MainActivity extends AppCompatActivity {
    ImageButton FullFoward;
    ImageButton Forward;
    ImageButton Backward;
    ImageButton Left;
    ImageButton Right;
    EditText Ip;
    Button Set;
    WebView Cam;

    public int port = 7891;
    public Socket socket;
    final byte[][] data = new byte[1][1];


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FullFoward = (ImageButton) findViewById(R.id.buttonFullFoward);
        Forward = (ImageButton) findViewById(R.id.buttonForward);
        Backward = (ImageButton) findViewById(R.id.buttonBackward);
        Left = (ImageButton) findViewById(R.id.buttonLeft);
        Right = (ImageButton) findViewById(R.id.buttonRight);
        Ip = (EditText) findViewById(R.id.editTextIp);
        Set = (Button) findViewById(R.id.buttonSet);
        Cam = (WebView) findViewById(R.id.Camera);

        FullFoward.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        data[0] = new byte[]{0x1};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        data[0] = new byte[]{0x2};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                }
                return false;
            }
        });

        Forward.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        data[0] = new byte[]{0x3};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        data[0] = new byte[]{0x4};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                }
                return false;
            }
        });

        Backward.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        data[0] = new byte[]{0x5};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        data[0] = new byte[]{0x6};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                }
                return false;
            }
        });

        Right.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        data[0] = new byte[]{0x7};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        data[0] = new byte[]{0x8};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                }
                return false;
            }
        });

        Left.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        data[0] = new byte[]{0x9};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                    case MotionEvent.ACTION_UP:
                        data[0] = new byte[]{0x10};
                        new Thread(new myTask2(data[0])).start();
                        return true; // if you want to handle the touch event
                }
                return false;
            }
        });

        Set.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new myTask(Ip.getText().toString())).start();
                Cam.loadUrl("http://" + Ip.getText().toString() + ":9090/stream/video.mjpeg");
            }
        });

        Cam.setWebViewClient(new WebViewClient(){
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                String message = "Camera Connection failed, is the server online? Please reload.";
                Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG);
                toast.show();
                Cam.loadUrl("about:blank");
                super.onReceivedError(view, request, error);
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.reload) {
            String message = "Reloading..";
            Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT);
            toast.show();
            Cam.loadUrl("http://" + Ip.getText().toString() + ":9090/stream/video.mjpeg");
        }
        return super.onOptionsItemSelected(item);
    }

    private class myTask implements Runnable {
        String address;

        myTask(String address) {
            this.address = address;
        }

        @Override
        public void run() {
            try {
                socket = new Socket(this.address, port);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private class myTask2 implements Runnable {
        byte[] data;

        myTask2(byte[] bytes) {
            this.data = bytes;
        }

        @Override
        public void run() {
            try {
                OutputStream out = socket.getOutputStream();
                out.write(this.data);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

0 个答案:

没有答案