java - 奇怪的行为 : sending image from Android phone to Java server (code working)

标签 java android sockets

我正在编写一个 android 应用程序,它可以将图像发送到运行 java 应用程序的服务器,并且它以一种非常奇怪的方式工作!

这是我的做法

  1. 在桌面上编译并运行 Java 应用程序,接收部分充当服务器
  2. 编译、部署和运行必须将图像发送到服务器的 android 部分。 android 应用程序完成执行但 java 应用程序没有
  3. 再次运行包含发送图像代码的 android 应用程序 Activity ,这一次,android 应用程序进度对话框卡住了,但是,java 应用程序完成执行并且图像也已成功传输...<

以下是 Java 应用程序接收部分的代码:

class ProjectServer
{
    ServerSocket serSock;
    Socket  sock;

    BufferedReader in;
    PrintWriter out;
    public static void main(String ar[])
    {
        try
        {
            ProjectServer cs=new ProjectServer();
            cs.startServer();
        }
        catch(Exception e)
        {

        }
    }

    public void startServer()
    {
        try
        {
            serSock=new ServerSocket(8070);
            System.out.println("Waiting for client...");
            sock=serSock.accept();

            System.out.println("Connections done");

        //Accept File
            System.out.println("Connected");

            //receive code
            int filesize=450660;
            int bytesRead;
            int current=0;
            // receive file
            byte [] mybytearray  = new byte [filesize];
            InputStream is = sock.getInputStream();
            FileOutputStream fos = new FileOutputStream("C:\\Project Server\\Capture.png");
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            bytesRead = is.read(mybytearray,0,mybytearray.length);
            current = bytesRead;

            do {
               bytesRead =
                  is.read(mybytearray, current, (mybytearray.length-current));
               if(bytesRead >= 0) current += bytesRead;
            } while(bytesRead > -1);

            bos.write(mybytearray, 0 , current);
            bos.flush();

            System.out.println("end-start");    
        }
        catch(Exception e)
        {
            System.out.println(e);
            e.printStackTrace();
        }

    }
}

以下是 Android 应用中 SEND 部分的代码:

package com.site.custom;
public class Act2 extends Activity
{
    private ProgressDialog pd;
    private String serverIP="58.146.100.187";
    private BufferedReader in;
    private PrintWriter out;
    private String path;
    private Socket cliSock;

    public void onCreate(Bundle onCreateInstance)
    {
        super.onCreate(onCreateInstance);
        setContentView(R.layout.act2);
        this.setTitle("This has started");
        path=getIntent().getStringExtra("path");

        //Establish Connection
        try
        {
            cliSock=new Socket(serverIP,8070);
            in=new BufferedReader(new InputStreamReader(cliSock.getInputStream()));

            ((TextView)findViewById(R.id.tview)).setText(path);
        }
        catch(Exception e)
        {
            Log.v("MERA MSG",e.toString());
        }

        //Send file
        ProgressDialog pd=ProgressDialog.show(this, "Sending image", "Image chosen:"+path.substring(path.lastIndexOf("//")+1),false,true);

        try
        {
            File myFile = new File (path);
            System.out.println((int)myFile.length());
            byte[] mybytearray  = new byte[450560];
            FileInputStream fis = new FileInputStream(myFile);
            BufferedInputStream bis = new BufferedInputStream(fis);
            bis.read(mybytearray,0,mybytearray.length);
            OutputStream os = cliSock.getOutputStream();
            System.out.println("Sending...");
            os.write(mybytearray,0,mybytearray.length);
            os.flush();
            System.out.println("Completed");

            pd.dismiss();
            System.out.println("Done");
        }
        catch(Exception e)
        {
            Log.v("MERA MSG",e.toString());
        }

    }
}

最佳答案

您没有关闭任何连接。您的服务器可能会等到连接关闭才知道数据已发送完毕。当您的客户端第二次运行时,第一个连接可能会被 Android 自动关闭,这允许您的服务器处理图像。但是,如果您的服务器处理图像的速度不够快,您的客户端可能会在第二次运行时“卡住”,因为它正在等待与服务器的成功端口连接,但服务器很忙。

长话短说,当您完成客户端连接时,您尝试close() 怎么样?调用 flush() 并没有真正告诉服务器任何数据已发送完毕。

如果您希望套接字保持打开状态,即使您关闭了 OutputStream,您可以编写一个自定义的 Socket 来覆盖 close() 方法,类似这样的东西......

public class MySocket extends Socket {

    public MySocket(String ipAddress, int port){
        super(ipAddress,port);
    }

    public void close(){
        // do nothing
    }

    public void reallyClose(){
        super.close();
    }
}

在您的代码中,将 cliSock=new Socket(serverIP,8070); 更改为 cliSock=new MySocket(serverIP,8070);

当您调用 OutputStream.close() 时,它会调用 MySocket 上的 close(),但如您所见,它不会实际上做任何事。当您完全使用完 Socket 后,您可以调用 MySocket.reallyClose();,它会正确关闭它。

关于java - 奇怪的行为 : sending image from Android phone to Java server (code working),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10161371/

相关文章:

android - 权限被拒绝从 SD 卡读取

sockets - 使用 luasocket 和代理获取 url 页面

Java 1.8升级Mockito匹配器编译错误

java - 文件编写器不写下单独的行

java - java中如何从XML中获取父元素属性和子元素值?

android - 从电话接收电话号码

java - 在 JAVA 中将列表对象添加到另一个列表中

android - 横向启动 Android 模拟器

c# - 是否有 SSLStream 以外的 C# 安全套接字?

linux - Python 服务器在 Linux 中不工作