Java 如何使用套接字从服务器发送和接收消息?

Java 如何使用套接字从服务器发送和接收消息?,java,android,sockets,tcp,server,Java,Android,Sockets,Tcp,Server,大家好,我有一个任务,我想向服务器发送一条消息,然后得到回复。我一直收到failed 1recvfrom failed:EBADF(坏文件描述符)error,我是这个套接字的新手。希望有人能帮我。以下是我的异步任务: private class SendDataAsyncTask extends AsyncTask<Void,Void,Void> { private String reply = ""; @Override p

大家好,我有一个任务,我想向服务器发送一条消息,然后得到回复。我一直收到
failed 1recvfrom failed:EBADF(坏文件描述符)
error,我是这个套接字的新手。希望有人能帮我。以下是我的异步任务:

 private class SendDataAsyncTask extends AsyncTask<Void,Void,Void>
    {
        private String reply = "";
        @Override
        protected Void doInBackground(Void... params)
        {
            try {
                Socket socket = new Socket("ip",portNumber);
                PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
                //printWriter.write("hello there");

                printWriter.println("hello there");
                bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                printWriter.flush();
                reply = bufferedReader.readLine();
                if(reply != null && !reply.equals(""))
                {
                    Log.d(SOCKET_TESTING_TAG,"my message is " + reply);
                }
                else
                {
                    Log.d(SOCKET_TESTING_TAG,"no message yet");
                }
                Log.d(SOCKET_TESTING_TAG,"break 3");
                printWriter.close();

            }
            catch (IOException e)
            {
                Log.d(SOCKET_TESTING_TAG,"failed " + e.getMessage());
                e.printStackTrace();
            }
            return null;
        }
        @Override
        public void onPostExecute(Void var)
        {
            tv_response.setText(reply);
        }
    }
私有类SendDataAsyncTask扩展了AsyncTask
{
私有字符串reply=“”;
@凌驾
受保护的Void doInBackground(Void…参数)
{
试一试{
插座插座=新插座(“ip”,端口号);
PrintWriter PrintWriter=新的PrintWriter(socket.getOutputStream());
//printWriter.write(“你好”);
printWriter.println(“你好”);
bufferedReader=新的bufferedReader(新的InputStreamReader(socket.getInputStream());
printWriter.flush();
reply=bufferedReader.readLine();
if(reply!=null&&!reply.equals(“”)
{
Log.d(SOCKET_TESTING_标记,“我的消息是”+回复);
}
其他的
{
Log.d(套接字测试标签,“还没有消息”);
}
日志d(插座测试标签,“断开3”);
printWriter.close();
}
捕获(IOE异常)
{
Log.d(SOCKET_TESTING_标记,“failed”+e.getMessage());
e、 printStackTrace();
}
返回null;
}
@凌驾
公共void onPostExecute(void var)
{
tv_response.setText(回复);
}
}
  • 注意:当我将if语句放在
    printWriter.flush()
    之前检查空读线时,仍然会得到一个错误
关闭套接字的输入或输出流将关闭另一个流和套接字。删除两个引用

if(bufferedReader.readLine() != null)
这没有道理。您正在丢弃该行,然后读取下一行,如果它不是空的。您需要将结果存储到变量中


您可能需要使用
printWriter.println()
而不是
printWriter.write()
。可能对方也在读行,而你没有发送行(没有行终止符)


如果
reply==null
,则表示对等方已关闭连接。不是“还没有消息”。空字符串可能是协议错误,但也不是“还没有消息”。

我更新了问题中的代码。我将bufferedReader.readLine()存储在
reply
变量中。但是,设置reply变量后的LOG语句没有运行,我不明白为什么,我希望我写的是正确的。您可能需要使用
printWriter.println()
而不是
printWriter.write()
。可能同行也在读行,而您没有发送行。printWriter没有我在android studio编译器上看到的println()方法。我不明白你说“peer也在读台词,而不是发一条”。你能澄清一下吗?行由行终止符终止,而您不发送行终止符,也不(现在)关闭套接字,因此对等端的
readLine()
将永远阻塞,这正是发生的情况。注意,你需要在阅读前冲洗它。哦,它起作用了!谢谢你。那么,您能否解释一下flush的作用以及为什么它需要出现在readLine()之前?
if(bufferedReader.readLine() != null)