我可以设置客户端 Socket
向服务器发送请求( sendData()
方法)并正确读取收到的消息( readData()
方法),但每次我使用 MOBILE_REQUEST
字符串通过这些代码向服务器发送请求时,我只收到消息:
@Override
protected Boolean doInBackground(String... params) {
try {
mSocket = new Socket(
// PC Ip is 192.168.1.199
// It is the other device, Not be local host : 127.0.0.1
Pas.pas.getPcIP(), 17001);
DataOutputStream mDos = new DataOutputStream(mSocket.getOutputStream());
String RESPONSE = null;
String MOBILE_BLOCK = "MobileBlock#";
// Converting collected data in byte array into String.
RESPONSE = sendData(mDos, MOBILE_BLOCK);
/**
* The result response from PC app in here
*/
// Log : response - #WindowsResp#192.168.1.199#
Log.i("", "response '" + RESPONSE + "'");
}
} catch (SocketTimeoutException e) {
IS_SOCKET_TIME_OUT = true;
e.printStackTrace();
} catch (ConnectException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
sendData()
方法 - 客户端将请求发送到服务器并等待获取响应数据 - 字符串数据 .
private String sendData(DataOutputStream mDos, String MOBILE_REQUEST) {
try {
// Log : MOBILE_REQUEST.getBytes() - [B@82f10f8
mDos.write(MOBILE_REQUEST.getBytes());
// todo I should set this sleep, bcs TCP has delay time,
// so i need set the delay time for client should receive data
// otherwise, sometimes I did not receive anything
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Log : #WindowsResp#192.168.1.199#
return new String(readData(mSocket));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
readData()
方法 - 从服务器收到数据后读取数据 .
public static byte[] readData(Socket mSocket) {
/* Since data are accepted as byte, all of them will be collected in the
following byte array which initialised with accepted data length. */
DataInputStream mDis = null;
try {
mDis = new DataInputStream(mSocket.getInputStream());
// Log : mDis.available() - 23
byte[] data = new byte[mDis.available()];
// Collecting data into byte array
for (int i = 0; i < data.length; i++)
data[i] = mDis.readByte();
// Log : data - [B@30c044a4
return data;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
我想要的是每次服务器通过单击按钮向我的套接字客户端发送消息,套接字客户端应该接收它 . 但在上面的代码中,它不是 .
请教我如何设置套接字客户端始终从服务器监听?
p / s:或者我需要设置 ServerSocket
?如果使用 ServerSocket
我不能使用相同的端口,对吧?因为当我首先打开 ServerSocket
进行侦听时(例如在端口17001),我无法使用客户端套接字通过端口17001发送请求,因为该端口已被使用 .
UPDATED
服务器(PC应用程序 - 笔记本电脑设备)发送到客户端(移动设备 - Android)的方式是通过Socket TCP,通过以下步骤:
1 - 客户端(Android设备)设置与服务器(PC应用程序)的TCP套接字连接(此连接永远不会关闭,直到在 onDestroy()
方法中退出应用程序) .
2 - 客户端向服务器发送请求,例如 MOBILE_REQUEST = "MobileID#MobileIP#"
3 - 服务器收到客户端的请求,它通过Socket连接回复客户端,实际上客户端正确接收了数据 . 恩 . "WindowsRep#WindowsIP"
这种方式对我不起作用,即使套接字TCP连接未关闭, getInputStream()
尚未关闭 . 在这种情况下 :
服务器通过Socket连接向客户端发送字符串数据,客户端正确接收数据 .
我想要的是每次“服务器通过Socket连接向客户端发送字符串数据,客户端正确接收数据” . 但就我而言,客户端只在向服务器发送请求后才接收数据 .
C# Server
服务器套接字
IPEndPoint ipe = new IPEndPoint("192.168.1.199", 17001);
svSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
svSocket.Bind(ipe);
服务器发送数据
string data_send = "#WBroad#" + "192.168.1.199" + "#";
byte[] byteData = Encoding.UTF8.GetBytes(data_send);
c.ClientSocket.Send(byteData);
1 回答
由于您尚未发布发送代码,因此无法确定您为何没有收到数据,但这里是对您发布的内容的快速评论:
你已经提出了这个问题,但现在调用这个方法毫无意义 . 您必须将套接字构造为
new Socket()
,没有参数,然后调用此方法,然后调用connect()
. 由于您没有提供要重复使用的源端口或IP地址,因此它仍然毫无意义 .这完全是对
available()
的误用 . 它不提供消息长度 . 见Javadoc . 没有理由相信在这一点上已经到达的任何数据(如果有的话)是完整的消息,或者只有一条消息 . 如果你想要消息,你将无法从TCP获得任何帮助:你必须自己实现它们 . 由于您的协议似乎是基于文本的,我建议您只使用行和readLine()
,使用BufferedReader
和BufferedWriter
而不是DataInput/OutputStreams
. 并在套接字的生命周期中构建一次,而不是每个应用程序消息一次,否则您将丢失数据 .huge 这个问题是它不会阻塞,因为大部分时间
available()
都是零,所以除了返回一个空的byte[]
数组之外,这个方法什么都不做 .在任何情况下,这完全等同于
mDis.readFully(data);
,效率只有几倍,但你不应该这样做:见上文 .这是不好的做法 . 你应该让这个方法抛出
IOException
并让调用者处理它 .往上看 . 这应包括行终止符,长度字前缀或其他一些分隔消息的方法 .
这种睡眠完全是浪费时间 . 和空间 . 去掉它 . 睡在网络代码中只是货物编程 .
这将抛出
NullPointerException
如果readData()
返回null
,如果有IOException
它会这样做,这是让该方法传播该异常而不是在内部捕获并返回null的另一个原因 .此方法与问题完全无关,因此不应发布 .
不,你为什么这么认为?
错误 .
又错了 . 事实并非如此 .
如上所述,当您不发布所有相关代码时,无法进一步帮助您,但是已经有足够的错误,你真的需要重新开始 .