Java Android客户端/笔记本服务器

Java Android客户端/笔记本服务器,java,android,Java,Android,我正在尝试创建一个客户端/服务器应用程序,其中,一台笔记本电脑充当服务器,与一台充当客户端的android手机共享其internet连接,我可以建立客户端和服务器之间的连接,问题是,当客户端尝试在套接字上写入时,它会被卡住。 这是android xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.co

我正在尝试创建一个客户端/服务器应用程序,其中,一台笔记本电脑充当服务器,与一台充当客户端的android手机共享其internet连接,我可以建立客户端和服务器之间的连接,问题是,当客户端尝试在套接字上写入时,它会被卡住。 这是android xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.giuseppe.client">
<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
</uses-permission>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
这是服务器代码

 import java.io.*;
 import java.net.*;
public class Server {

public static void main(String[] args) {
    int port=5555;
    byte[] buff =new byte[1024];
    String str; 
    // TODO Auto-generated method stub
    try {
        ServerSocket server=new ServerSocket(port);
        System.out.println("Before accept");
        Socket client=server.accept(); 
        System.out.println("After accept");
        DataInputStream in=new DataInputStream(new BufferedInputStream(client.getInputStream()));
        str=in.readUTF();

        
        System.out.println("Message received");
        in.close();
        client.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
}

}
我想问题出在客户端,因为我还试图使用服务器发送字符串,而服务器发送字符串时,客户端没有收到。 对不起,我的英语不好。多谢大家

+++++编辑+++++

我还尝试了OutputStream out=socket.getOutputStream;然后是out.writestr.getBytes,但在这种情况下,当我尝试在套接字中写入时,它会卡在这里,这可能是任何android配置的问题吗?

免责声明:我无法验证您的android代码的正确性,所以我假设这是可以的,并且只对您的网络代码进行注释,这是您问题的根本原因

代码中的两个主要问题是:

在您的服务器代码中,您一直在读,什么也不做 您的服务器是单线程的 你的主要问题是上面的1,一旦你解决了你的1,你就会得到另一个问题,那就是2

您的1个问题是,您需要定义一些有关如何考虑流结束或输入的逻辑,请参阅下面的代码示例,阅读代码中的注释,也不一定需要使用RealUTF方法,相反,您可以使用I/O桥接类,如InputStreamReader,它充当字节流和字符流之间的桥接器,因此您可以使用InputStreamReader clientSocketReader=new InputStreamReaderClient Socket.getInputStream,UTF8;,我不能说为什么您真的需要DataInputStream,并且不能使用InputStreamReader,但在我看来,您可以使用桥接类

    int portNumber = 8001;
    try {
        ServerSocket serverSocket = new ServerSocket(portNumber);
        Socket clientSocket = serverSocket.accept();
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        String inputLine;
        while ((inputLine = in.readLine()) != null) { // **** this basically means that read one full line, you have to specify condition like this, so suppose you have created a telnet session with this server now keep on typing and as soon you will hit entered then while block processing will start. 
            System.out.println("@@@ " + inputLine);
            out.println(inputLine); // *** here same input is written back to the client, so suppose you have telnet session then same input can be seen
        }
    } catch (IOException e) {
        System.out.println(
                "Exception caught when trying to listen on port " + portNumber + " or listening for a connection");
        System.out.println(e.getMessage());
    }
现在你的2个问题是你的服务器是单线程的,你需要一个多线程的服务器,这基本上意味着你应该在一个新的线程中处理每个客户端请求。阅读我的文章,其中对单线程v/s多线程服务器有更多的了解。请参见以下多线程服务器的代码示例:

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;

import com.learn.Person;

/**
 * @author himanshu.agrawal
 *
 */
public class TestWebServer2 {

    public static void main(String[] args) throws IOException {
        startWebServer();
    }

    /**
     * test "backlog" in ServerSocket constructor
test -- If <i>bindAddr</i> is null, it will default accepting
     * connections on any/all local addresses.
     * @throws IOException
     */

    private static void startWebServer() throws IOException {
        InetAddress address = InetAddress.getByName("localhost");
        ServerSocket serverSocket = new ServerSocket(8001, 1, address);
        // if set it to 1000 (1 sec.) then after 1 second porgram will exit with SocketTimeoutException because server socket will only listen for 1 second.
        // 0 means infinite
        serverSocket.setSoTimeout(/*1*/0000);

        while(true){
            /*Socket clientSocket = serverSocket.accept();*/ // a "blocking" call which waits until a connection is requested
            System.out.println("1");
            TestWebServer2.SocketThread socketThread = new TestWebServer2().new SocketThread();
            try {
                socketThread.setClientSocket(serverSocket.accept());
                Thread thread = new Thread(socketThread);
                thread.start();
                System.out.println("2");
            } catch (SocketTimeoutException socketTimeoutException) {
                System.err.println(socketTimeoutException);
            }
        }

    }

    public class SocketThread implements Runnable{

        Socket clientSocket;

        public void setClientSocket(Socket clientSocket) throws SocketException {
            this.clientSocket = clientSocket;
            //this.clientSocket.setSoTimeout(2000); // this will set timeout for reading from client socket.
        }

        public void run(){
            System.out.println("####### New client session started." + clientSocket.hashCode() + " | clientSocket.getLocalPort(): " + clientSocket.getLocalPort()
                    + " | clientSocket.getPort(): " + clientSocket.getPort());
            try {
                listenToSocket(); // create this method and you implement what you want to do with the connection.
            } catch (IOException e) {
                System.err.println("#### EXCEPTION.");
                e.printStackTrace();
            }
        }


    }

}
这是一个艺术生产者/消费者的问题。服务器从accept返回后,客户端与服务器建立了一个eTablied连接。
当服务器等待数据读取消费者时,客户端生产者什么也不做。客户端应该在套接字上写入一些内容才能继续

请在您的问题中添加其他信息。您可以直接对其他人的答案进行评论以作出回应。相反,您输入了一个答案作为响应,它似乎没有回答您的问题感谢您的快速重播。我试图在单击按钮后在套接字上写入一些内容,事实上我在onClick android的方法中调用output.writeUTF,问题是,当我执行flush方法时,客户端什么也不做。感谢快速重播,对于问题1,我用同一台笔记本电脑中的其他客户端尝试了这个服务器,它工作了,现在的逻辑是在收到一行时只打印一条消息,我还尝试了InputStream in=client.getInputStream;但问题是服务器没有收到任何东西,对我来说,问题出在客户端,因为它卡在out.flush方法中。对于问题2,是的,你是对的,我应该实现一个多线程服务器,但事实是现在我只有一个客户端,但问题是服务器没有收到任何东西-服务器将收到如果你使用我上面提到的代码,你需要使用sysout打印东西,另外,如果您还没有在客户端中执行类似的修复,那么您也需要在客户端中执行类似的修复,请检查此示例客户端-。。此外,我建议您阅读Oracle的自定义n/w跟踪信息-。。。特别是关于插座的部分。
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;

import com.learn.Person;

/**
 * @author himanshu.agrawal
 *
 */
public class TestWebServer2 {

    public static void main(String[] args) throws IOException {
        startWebServer();
    }

    /**
     * test "backlog" in ServerSocket constructor
test -- If <i>bindAddr</i> is null, it will default accepting
     * connections on any/all local addresses.
     * @throws IOException
     */

    private static void startWebServer() throws IOException {
        InetAddress address = InetAddress.getByName("localhost");
        ServerSocket serverSocket = new ServerSocket(8001, 1, address);
        // if set it to 1000 (1 sec.) then after 1 second porgram will exit with SocketTimeoutException because server socket will only listen for 1 second.
        // 0 means infinite
        serverSocket.setSoTimeout(/*1*/0000);

        while(true){
            /*Socket clientSocket = serverSocket.accept();*/ // a "blocking" call which waits until a connection is requested
            System.out.println("1");
            TestWebServer2.SocketThread socketThread = new TestWebServer2().new SocketThread();
            try {
                socketThread.setClientSocket(serverSocket.accept());
                Thread thread = new Thread(socketThread);
                thread.start();
                System.out.println("2");
            } catch (SocketTimeoutException socketTimeoutException) {
                System.err.println(socketTimeoutException);
            }
        }

    }

    public class SocketThread implements Runnable{

        Socket clientSocket;

        public void setClientSocket(Socket clientSocket) throws SocketException {
            this.clientSocket = clientSocket;
            //this.clientSocket.setSoTimeout(2000); // this will set timeout for reading from client socket.
        }

        public void run(){
            System.out.println("####### New client session started." + clientSocket.hashCode() + " | clientSocket.getLocalPort(): " + clientSocket.getLocalPort()
                    + " | clientSocket.getPort(): " + clientSocket.getPort());
            try {
                listenToSocket(); // create this method and you implement what you want to do with the connection.
            } catch (IOException e) {
                System.err.println("#### EXCEPTION.");
                e.printStackTrace();
            }
        }


    }

}