首页 文章

Android Client / Laptop Server

提问于
浏览
0

我正在尝试创建一个客户端/服务器应用程序,其中,笔记本电脑就像服务器一样,与一个像客户端一样的Android手机共享其互联网连接,我可以 Build 客户端和服务器之间的连接,问题是当客户端尝试时在套接字上写,它会卡在那里 . 这是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>

这是android客户端

package com.example.giuseppe.client;

import java.io.*;
import java.net.*;


import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;


import org.w3c.dom.Text;

import static java.net.InetAddress.*;

public class MainActivity extends Activity {
    private Socket socket;
    private static final int port=5555;
private static final String addr="192.168.1.37";


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    new Thread(new Client()).start();
}

public void onClick(View view){
    try{
        TextView tx=(TextView) findViewById(R.id.txt);

        EditText et= (EditText) findViewById(R.id.et);
        String str= et.getText().toString();
        DataOutputStream out= new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())) ;
        out.writeUTF(str);
        out.close();
        socket.close();

    }catch(UnknownHostException e){
        e.printStackTrace();
    }catch (IOException e){
        e.printStackTrace();
    }catch (Exception e){
        e.printStackTrace();
    }
}

class Client implements Runnable {
    @Override
    public void run() {
        try {
            TextView tx= (TextView) findViewById(R.id.txt);
            tx.setText("Before connection");
            InetAddress server = InetAddress.getByName(addr);
            socket = new Socket("192.168.1.37", port);
            tx.setText("After connection");
        } catch (UnknownHostException a) {

        } catch (IOException a) {

        } catch (Exception a){

        }
    }
}

这是服务器代码

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.write(str.getBytes()),但是在这种情况下它会卡在这里,当我尝试在套接字中写入时,可能是任何android的配置问题?

2 回答

  • 1

    免责声明:我无法验证您的Android代码的正确性,所以我假设这很好,只评论您的网络代码,这是您的问题的根本原因 .

    您的代码中的2个主要问题是:

    • 在您的服务器代码中,您正在阅读和阅读,什么都不做

    • 您的服务器是单线程的

    你的主要问题是上面的#1,一旦你解决了你的#1,你将会遇到另一个问题#2 .

    Your #1 problem 是你需要定义一些关于如何考虑流结束或输入的逻辑,参考下面的代码示例( read the comments in the code ),你也不一定需要使用 readUTF 方法,而是可以使用“ I/O bridge classes ”之类的 InputStreamReader 充当 byte streamcharacter stream 之间的桥梁,所以你可以使用 InputStreamReader clientSocketReader = (new InputStreamReader(clientSocket.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());
        }
    

    Now your #2 problem 是您的服务器是单线程的,您需要有一个多线程服务器,这基本上意味着您应该在新线程中处理每个客户端请求 . 阅读我的this answer,这会在单线程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();
                }
            }
    
    
        }
    
    }
    
  • 0

    那是一个艺术问题 . 服务器从接受返回后,客户端已 Build 与服务器的连接 . 当Sever正在等待数据读取(消费者)时,客户端( 生产环境 者)什么都不做 . 客户端 should write something on The Socket 为了继续 .

相关问题