android - 如何运行2个套接字到同一个IP和端口?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android - 如何运行2个套接字到同一个IP和端口?相关的知识,希望对你有一定的参考价值。
所以我正在制作一个非常小的消息应用。我有1个异步任务,用于侦听来自服务器的消息,以及另一个异步任务,它将消息发送到服务器并回送消息。由于某种原因,我无法同时发送和收听服务器。这是发生的顺序的顺序:
1.User A输入消息并单击发送。什么都没发生。 2.User B,(关闭侦听异步任务)并发送消息,然后返回userA的消息以及用户Bs。我不知道为什么我的用户A不能同时发送和收听消息。这是我的2个异步任务。
private class CommunicateWithServerAsyncTask extends AsyncTask<Void,Void,Void>
{
private String jsonReply = "";
private String jsonOutputToServer = "";
public CommunicateWithServerAsyncTask(String jsonMessage)
{
this.jsonOutputToServer = jsonMessage;
}
@Override
protected Void doInBackground(Void... params)
{
Log.d(SOCKET_TESTING_TAG,"break 1");
try
{
Log.d(SOCKET_TESTING_TAG,"break 2");
Socket socket = new Socket("ip",portNumber);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
printWriter.println(jsonOutputToServer);
printWriter.flush();
jsonReply = bufferedReader.readLine();
Log.d(SOCKET_TESTING_TAG,"break 2");
if(jsonReply != null && !jsonReply.equals(""))
{
Log.d(SOCKET_TESTING_TAG,"break 3");
Log.d(SOCKET_TESTING_TAG,"my message is " + jsonReply);
}
else
{
Log.d(SOCKET_TESTING_TAG,"break 4");
Log.d(SOCKET_TESTING_TAG,"no message yet");
}
printWriter.close();
bufferedReader.close();
socket.close();
}
catch (IOException e)
{
Log.d(SOCKET_TESTING_TAG,"failed " + e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(Void var)
{
displayMessageFromServer(jsonReply,false);
}
}
第二个异步任务
private class ListenForMessagesAsyncTask extends AsyncTask<Void,Void,Void>
{
private String jsonReply = "";
//private BufferedReader bufferedReader;
@Override
protected Void doInBackground(Void... params)
{
Log.d(SOCKET_TESTING_TAG,"break A");
try
{
Socket socket = new Socket("52.91.109.76",1234);;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (isListeningForMessages)
{
Log.d(SOCKET_TESTING_TAG,"break D");
Log.d(SOCKET_TESTING_TAG,"my buffer reader value is " + String.valueOf(bufferedReader.ready()));
if(bufferedReader.ready())
{
Log.d(SOCKET_TESTING_TAG,"break E");
jsonReply = (String) bufferedReader.readLine();
Log.d(SOCKET_TESTING_TAG,"break F");
isListeningForMessages = false;//we have a reply, close the while loop and Async Task.
Log.d(SOCKET_TESTING_TAG,"my listening message is " + jsonReply);
}
}
bufferedReader.close();
socket.close();
}
catch (IOException e)
{
Log.d(SOCKET_TESTING_TAG,"failed " + e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(Void var)
{
displayMessageFromServer(jsonReply,true);
}
}
我想要一种非常简单的方法让用户1向服务器发送消息。服务器回应响应并将该消息发送给用户2。
要完成向服务器发送消息并获得echo响应,您可以查看CommunicateWithServerAsyncTask。在这里,我们使用套接字对象连接到服务器,我们可以使用Typewriter类将消息发送到服务器。接下来,我们使用缓冲区读取器类来侦听来自服务器的任何消息响应。
为了让用户2从服务器接收用户1的消息,我们必须不断地监听服务器的响应,这就是我实现CommunicateWithServerAsyncTask的原因。与第一个AsyncTask相同的概念,但我们只需要while循环中的socket和bufferreader对象。
希望这可以帮助那些试图找出套接字连接基础知识的人。在这个答案中,我已经假设你有一个服务在某个地方运行,并在客户端需要帮助。
public class MainActivity extends AppCompatActivity
{
private Button b_send;
private EditText et_message;
private TextView tv_response, userB_TV;
private boolean isSendButtonPressed;
private final String SOCKET_TESTING_TAG = "SOCKET_TESTING_TAG";
private static boolean isListeningForMessages = true;
private Socket socket;
private BufferedReader bufferedReader;
private ListenForMessagesAsyncTask listenForMessagesAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindActivity();
}
private void bindActivity()
{
b_send = (Button) findViewById(R.id.b_send);
et_message = (EditText) findViewById(R.id.et_message);
tv_response = (TextView) findViewById(R.id.tv_response);
userB_TV = (TextView) findViewById(R.id.tv_history);
tv_response.setMovementMethod(new ScrollingMovementMethod());
b_send.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view)
{
if(!et_message.getText().toString().isEmpty() && !isSendButtonPressed)//I do a couple checks to make sure the user doesn't send an empty string and that they don't keep tapping the button
{
isSendButtonPressed = true;
listenForMessagesAsyncTask.cancel(true);
try
{
socket.close();
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
CommunicateWithServerAsyncTask communicateWithServerAsyncTask = new CommunicateWithServerAsyncTask(convertMessageToJson(et_message.getText().toString()));
communicateWithServerAsyncTask.execute();//Note: you could do new CommunicateWithServerAsyncTask.execute(""); However, im just used to initiating async tasks this way.
}
}
});
listenForMessagesAsyncTask = new ListenForMessagesAsyncTask();
listenForMessagesAsyncTask.execute();
}
private class CommunicateWithServerAsyncTask extends AsyncTask<Void,Void,Void>
{
private String jsonReply = "";
private String jsonOutputToServer = "";
public CommunicateWithServerAsyncTask(String jsonMessage)
{
this.jsonOutputToServer = jsonMessage;
}
@Override
protected Void doInBackground(Void... params)
{
try
{
Socket socket = new Socket("ip",portNumber);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
printWriter.println(jsonOutputToServer);
printWriter.flush();
jsonReply = bufferedReader.readLine();
if(jsonReply != null && !jsonReply.equals(""))
{
Log.d(SOCKET_TESTING_TAG,"my message is " + jsonReply);
}
else
{
Log.d(SOCKET_TESTING_TAG,"no message yet");
}
printWriter.close();
bufferedReader.close();
socket.close();
}
catch (IOException e)
{
Log.d(SOCKET_TESTING_TAG,"failed " + e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(Void var)
{
displayMessageFromServer(jsonReply,false);
}
}
private class ListenForMessagesAsyncTask extends AsyncTask<Void,Void,Void>
{
private String jsonReply = "";
//private BufferedReader bufferedReader;
@Override
protected Void doInBackground(Void... params)
{
try
{
socket = new Socket("ip",portNumber);;
bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (isListeningForMessages)
{
//Log.d(SOCKET_TESTING_TAG,"break D");
if(bufferedReader.ready())
{
Log.d(SOCKET_TESTING_TAG,"break E");
jsonReply = (String) bufferedReader.readLine();
Log.d(SOCKET_TESTING_TAG,"break F");
isListeningForMessages = false;//we have a reply, close the while loop and Async Task.
Log.d(SOCKET_TESTING_TAG,"my listening message is " + jsonReply);
}
}
bufferedReader.close();
socket.close();
}
catch (IOException e)
{
Log.d(SOCKET_TESTING_TAG,"failed " + e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
public void onPostExecute(Void var)
{
displayMessageFromServer(jsonReply,true);
}
}
以上是关于android - 如何运行2个套接字到同一个IP和端口?的主要内容,如果未能解决你的问题,请参考以下文章
AsyncTask和套接字在android java中不起作用
如何在 Android Java 中将 MAC 地址转换为 IP?