套接字被关闭了吗? (Android和Python)

时间:2018-11-02 18:30:05

标签: java android python sockets

我试图在我的Android应用程序中使用套接字,但是遇到了一个小问题。

我使用python创建服务器,一切正常。服务器从Android客户端接收到消息,但似乎无法得到响应。

这是我的server.py:

import socket

HOST = '10.10.0.153'
PORT = 7800

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket created')

try:
    s.bind((HOST, PORT))
except socket.error as err:
    print('binding faild')
s.listen(10)


while 1:
    conn, addr = s.accept()
    print('Connect with ' + addr[0] + ':' + str(addr[1]))
    buf = conn.recv(1024)
    print(buf)
    data = "hello"
    conn.send(data.encode('utf-8'))
s.close()

这是服务器端:

public class Sender extends AsyncTask<String, Void, Void> {

    private final String TAG = "Sender";

    Socket s;
    PrintWriter pw;

    @Override
protected Void doInBackground(String... strings) {

    String message = strings[0];

    try {
        s = new Socket(GlobalVars.SERVER, GlobalVars.PORT);
        pw = new PrintWriter(s.getOutputStream());

        pw.write(message);
        pw.flush();

        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        System.out.println("1");
        //String msg = in.readLine();
        System.out.println("2");
        //System.out.println(msg);
        System.out.println("3");

        pw.close();
        s.close();
    } catch(IOException e) {
        e.printStackTrace();
        Log.e(TAG, "IOException 1");
    }
}
  • 编辑-我不再收到此错误。下去看看新问题 我收到的错误是IOException,它说套接字已关闭,但是我找不到在何处关闭它。

错误:

W/System.err: java.net.SocketException: Socket is closed
                  at java.net.Socket.getInputStream(Socket.java:935)
W/System.err:     at net.traveler.liel.traveler.Server.Sender.doInBackground(Sender.java:34)
                  at net.traveler.liel.traveler.Server.Sender.doInBackground(Sender.java:14)
                  at android.os.AsyncTask$2.call(AsyncTask.java:333)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
                  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
                  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err:     at java.lang.Thread.run(Thread.java:764)
E/Sender: IOException 1

新问题:当我尝试获取响应(in.readLine())时,它只是停止工作,好像服务器没有将任何内容发回。

3 个答案:

答案 0 :(得分:0)

尝试从您的代码中删除pw.close();。 也尝试删除此内容:

  if(!s.isClosed()) {
        try {
            s.close();
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "IOException 2");
        }
    }

答案 1 :(得分:0)

我向您推荐以下内容:

使用 SocketIO 从Python连接到Java。参见here

您还可以使用Flask构建HTTP(S)服务器并连接Java服务器> here

使用原始套接字从来都不是生产的好主意,我更喜欢Netty用于Java应用程序,而Spring则用于RESTful服务。

此外,您的代码正在主线程中运行,并且如果客户端断开连接,Python服务器会自行中断。

请勿在生产中使用此代码!这是不安全的!

您也可以使用Java构建它:

public class NetworkServer {

public void run(String address, int port) throws InterruptedException {
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.childHandler(new PipelineInjector())
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 100)
                .option(ChannelOption.SO_RCVBUF, 4096)
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(4096));


        ChannelFuture f = b.bind(address, port).sync();
        System.out.println("Network server succesfully bound to :" + address + ":" + port);
        try {
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            System.out.println("Couldn't bind server to :" + address + ":" + port);
            System.exit(1);
        }
    } finally {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }

}

和客户:

public class NetworkClient {

public void run(String address, int port) throws InterruptedException {
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    try {
        Bootstrap b = new Bootstrap();
        b.childHandler(new PipelineInjector())
                .group(bossGroup, workerGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 100)
                .option(ChannelOption.SO_RCVBUF, 4096)
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(4096));


        ChannelFuture f = b.connect(address, port).sync();

        try {
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            System.exit(1);
        }
    } finally {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    } }

此示例显示了Netty客户端和Netty服务器。 Netty非常有用,而且效果很好。 Netty可能有点困难,但效果很好。

为了安全地使用Netty ,您需要使用 TLS / SSL 对所有邮件进行加密。 此外,您应该添加消息队列以将无法发送的消息加入队列。 建立网络的方法很多,也许您对其中一种方法感到满意。

答案 2 :(得分:0)

在Java方面,您要求读取“行”。行必须以换行符(docs)结尾。如果没有换行,您的Java代码将坐在那里,在readLine()内阻塞,等待换行到达。将您的python代码更改为此:

data = "hello\n"