3 回答

TA貢獻1845條經驗 獲得超8個贊
試試看:
socket = new java.net.Socket(inetAddress,MainActivity.wifiModulePort);
//read input msg from server
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeChars(CMD);
System.out.println(CMD);
dataOutputStream.close();
socket.close();
如果這增加了額外的空間,那么簡單的解決方案是繼續使用 writeutf 并在服務器端對數據進行子字符串化
socket = new java.net.Socket(inetAddress,MainActivity.wifiModulePort);
//read input msg from server
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.writeUTF(CMD);
System.out.println(CMD);
dataOutputStream.close();
socket.close();
在服務器端:
data = tcpCliSock.recv(BUFSIZE).decode()
data = data[2:]
引用自 Javadoc:
以與機器無關的方式使用修改后的 UTF-8 編碼將字符串寫入基礎輸出流。
首先,將兩個字節寫入輸出流,就像使用 writeShort 方法一樣,給出后面的字節數。這個值是實際寫出的字節數,而不是字符串的長度。在長度之后,字符串的每個字符按順序輸出,使用字符的修改后的 UTF-8 編碼。如果沒有拋出異常,寫入的計數器將增加寫入輸出流的字節總數。這將至少是 str 長度的兩倍,最多是 str 長度的兩倍。

TA貢獻1757條經驗 獲得超8個贊
請向服務器提供您的 Android 代碼片段(您發送消息的位置)。
當我在本地機器上運行代碼時(我沒有樹莓派控制器,所以我注釋掉了某些行):
import sys
import socket
import select
ctrCmd = ['Up', 'Down', 'Left', 'Right', 'Stop', 'Connect']
HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(1)
print('Waiting for connection')
sendInterval = 1.0 # interval(sec) for sending messages to connected clients
rxset = [tcpSerSock]
txset = []
while True:
print("Waiting for connection")
tcpCliSock, addr = tcpSerSock.accept()
print("...connected from :", addr)
try:
while True:
data = ''
data = tcpCliSock.recv(BUFSIZE).decode()
print("This", data)
if not data:
print("No Data", data)
break
if data == ctrCmd[0]:
print("I am here")
# Servomotor.ServoUp()
print("Increase: ")
#tcpCliSock.send("Servo Increases".encode())
if data == ctrCmd[1]:
# Servomotor.ServoDown()
print("Decrease: ")
#tcpCliSock.send("Servo Decreases".encode())
if data == ctrCmd[2]:
# Servomotor.ledOn()
print("Led On")
#tcpCliSock.send("Led On".encode())
if data == ctrCmd[3]:
# Servomotor.ledOff()
print("Led Off")
# tcpCliSock.send("Led Off".encode())
except KeyboardInterrupt:
# Servomotor.close()
# GPIO.cleanup()
print('Exception')
tcpSerSock.close()
在客戶端運行以下代碼:
import sys
import socket
import time
ctrCmd = [b'Up', b'Down', b'Left', b'Right', b'Stop', b'Connect']
HOST = '127.0.0.1'
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpCliSock.connect(ADDR)
time.sleep(1)
for i in range(len(ctrCmd)):
tcpCliSock.send(ctrCmd[i])
time.sleep(1)
data = tcpCliSock.recv(BUFSIZE)
print(data)
tcpCliSock.close()
我最終收到的是:
Waiting for connection
Waiting for connection
...connected from : ('127.0.0.1', 54430)
This Up
I am here
Increase:
This Down
Decrease:
This Left
Led On
This Right
Led Off
This Stop
This Connect
您可能已經注意到,關鍵是在客戶端我發送的不是字符串而是字節數組(b'Up',而不是'Up')。因此,如您所見,服務器端沒有問題。
可能在你的 Android 端你需要這樣的東西:
String msg = "Up"
byte[] byteArr = msg.getBytes();
更新
好的,我想我知道那里發生了什么。使用套接字的輸出流,您只能發送字節數據。它實際上所做的是將您的消息轉換為字節數組 (CMD.getBytes())。毫不奇怪,您的服務器正在一步一步、逐字節地接收所有內容。你需要做的是:
public class MainActivity extends AppCompatActivity {
//UI Element
Button btnUp;
Button btnDown;
Button btnLedOn;
Button btnLedOff;
EditText txtAddress;
/*TextView message;*/
Socket myAppSocket = null;
public static String wifiModuleIp = "";
public static int wifiModulePort = 0;
public static String CMD = "0";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnUp = (Button) findViewById(R.id.btnUp);
btnDown = (Button) findViewById(R.id.btnDown);
btnLedOn = (Button) findViewById(R.id.btnLedOn);
btnLedOff = (Button) findViewById(R.id.btnLedOff);
txtAddress = (EditText) findViewById(R.id.ipAddress);
/*message = (TextView) findViewById(R.id.message);*/
btnUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getIPandPort();
CMD = "Up";
Socket_AsyncTask cmd_increase_servo = new Socket_AsyncTask();
cmd_increase_servo.execute();
}
});
btnDown.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getIPandPort();
CMD = "Down";
Socket_AsyncTask cmd_increase_servo = new Socket_AsyncTask();
cmd_increase_servo.execute();
}
});
btnLedOn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getIPandPort();;
CMD = "ON";
Socket_AsyncTask cmd_led_on = new Socket_AsyncTask();
cmd_led_on.execute();
}
});
btnLedOff.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getIPandPort();
CMD = "OFF";
Socket_AsyncTask cmd_led_off = new Socket_AsyncTask();
cmd_led_off.execute();
}
});
}
public void getIPandPort()
{
String iPandPort = txtAddress.getText().toString();
Log.d("MYTEST","IP String: "+ iPandPort);
String temp[]= iPandPort.split(":");
wifiModuleIp = temp[0];
wifiModulePort = Integer.valueOf(temp[1]);
Log.d("MY TEST","IP:" +wifiModuleIp);
Log.d("MY TEST","PORT:"+wifiModulePort);
}
public class Socket_AsyncTask extends AsyncTask<Void,Void,Void>
{
Socket socket;
OutputStreamWriter osw;
@Override
protected Void doInBackground(Void... params){
try{
InetAddress inetAddress = InetAddress.getByName(MainActivity.wifiModuleIp);
socket = new java.net.Socket(inetAddress,MainActivity.wifiModulePort);
//read input msg from server
osw = new OutputStreamWriter(socket.getOutputStream(), 'UTF-8');
osw.write(CMD, 0, CMD.length());
out.flush();
socket.close();
}catch (UnknownHostException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}
return null;
}
}
}

TA貢獻1802條經驗 獲得超6個贊
if not "some string"不會等于 True。您可能想將其更改為:
if data != "" :
# process here
pass
您在單獨的行中收到數據,可能是因為單獨發送。你可以看看我曾經為 TCP 套接字編寫的代碼。 套接字
也ctrCmd[0]等于'Up'和你的數據內容,正如我在 shell 中看到的那樣,是像'U'和這樣的字符'P'。所以這條線
if data == ctrCmd[0]:
print("I am here")
不會運行,因為'Up'不等于'U'.
添加回答
舉報