我试图在我的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");
}
}
错误:
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())时,它只是停止工作,好像服务器没有将任何内容发回。
答案 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"