socket传输对象问题

socket传输对象问题

程序中message的消息始终拿不到,真的不知道哪里有问题,请老师指点!


//tcp服务端
package com.example.jeremychen.tcpconnectionpractice;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by jeremychen on 2018/6/19.
 */

public class TcpServer {

    public void start()
    {
        try {
            ServerSocket serverSocket = new ServerSocket(9090);
            MsgPool.getInstance().disPatch();
            // TODO: 2018/6/19 一直不停的等待是否有clientsocket的链接产生
            while(true)
            {
                Socket socket = serverSocket.accept();
                if(socket != null)
                {
                    System.out.println(socket.getInetAddress() + "has been connected with server!");
                }
                ProcessThread thread = new ProcessThread(socket);
                MsgPool.getInstance().addComingListener(thread);
                thread.start();
                // TODO: 2018/6/19 每当有一个客户端socket产生,都将单另开启一个线程来进行处理
                // TODO: 2018/6/19 server 中不可以写入消息
            }

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

    public static void main(String[] args)
    {
        new TcpServer().start();
    }
}

//tcp客户端
package com.example.jeremychen.tcpconnectionpractice;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created by jeremychen on 2018/6/19.
 */

public class ClientSocket {
    private Scanner scanner;

    public ClientSocket() {
        this.scanner = new Scanner(System.in);
        scanner.useDelimiter("\n");
    }

    private void start()
    {
        try {
            Socket socket = new Socket("100.64.12.11", 9090);
            final ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());

            new Thread(){
                @Override
                public void run() {
                    super.run();
                    //String content = null;
                    try {
                        while(true)
                        {
                            Message message = (Message) objectInputStream.readObject();
                            System.out.println(message.getPort() + message.getContent());
                        }
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();

            while(true)
            {
                Message message = new Message();
                String content = scanner.next();
                message.setPort(socket.getPort());
                message.setContent(content);
                objectOutputStream.writeObject(message);
                objectOutputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void  main(String[] args)
    {
        new ClientSocket().start();
    }
}

//message自定义的消息类
package com.example.jeremychen.tcpconnectionpractice;

import java.io.Serializable;

/**
 * Created by jeremychen on 2018/6/19.
 */

public class Message implements Serializable{


    private static final long serialVersionUID = 1L;
    private int port;
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }
}

//观察者模式的接口
package com.example.jeremychen.tcpconnectionpractice;

/**
 * Created by jeremychen on 2018/6/19.
 */

public interface MsgComingListener {
    void msgCommingListener(Message object);
}

//server中的消息池
package com.example.jeremychen.tcpconnectionpractice;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Created by jeremychen on 2018/6/19.
 */

public class MsgPool {
    private static MsgPool msgPool = new MsgPool();
    private LinkedBlockingQueue<Message> mQueue = new LinkedBlockingQueue<>();
    private List<MsgComingListener> listenerList = new ArrayList<>();

    public static MsgPool getInstance(){
        return msgPool;
    }


    public void disPatch()
    {
        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    while(true){
                        Message object = mQueue.take();
                        MakeMsgNotified(object);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    public void MakeMsgNotified(Message object) {
        for(MsgComingListener listener : listenerList)
        {
            listener.msgCommingListener(object);
        }
    }

    public void addComingMsg(Message message)
    {
        try {
            mQueue.put(message);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void addComingListener(MsgComingListener listener)
    {
        listenerList.add(listener);
    }
}

//server中没收到一个客户端时启动的线程
package com.example.jeremychen.tcpconnectionpractice;

import android.util.Log;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 * Created by jeremychen on 2018/6/19.
 */

public class ProcessThread extends Thread implements MsgComingListener {

    private InputStream inputStream;
    private OutputStream outputStream;
    private Socket msocket;


    public ProcessThread(Socket socket){
        try {
            this.msocket = socket;
            inputStream = socket.getInputStream();
            outputStream = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        super.run();
        // TODO: 2018/6/19 此线程用于读取inputsteam中的消息
        try {
            ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(inputStream));
            Message object = null;
            while((object = (Message) objectInputStream.readObject()) != null)
            {
                System.out.println(object.getPort() + "发来的消息是:" + object.getContent());
                MsgPool.getInstance().addComingMsg(object);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void msgCommingListener(Message object) {
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
            objectOutputStream.writeObject(object);
            objectOutputStream.flush();
        } catch (IOException e) {

        }
    }
}

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

4回答
提问者 Jeremy936399 2018-06-20 13:55:55

老师还是不行啊,我在客户端输入消息,server端还是收不到发来的消息啊老师

  • ClientSocket类的objectOutputStream和objectInputStream的地方阻塞了。你去它们的下一行,增加 System.out.println(”hello“)输不出来吧。换成普通的输入输出流
    2018-06-20 19:20:08
  • 提问者 Jeremy936399 回复 好帮手慕雪 #2
    哇塞,好的老师,已经搞定了,能说一下发生这种情况的原因吗?
    2018-06-21 02:55:50
  • 好帮手慕雪 回复 提问者 Jeremy936399 #3
    ObjectInputStream不能直接使用,你得判断InputStream以及BufferedInputStream,都有内容才能直接readObject,包括while(true)不停的读呀,没内容能读出什么来呀。一般的客户端与服务器事先约定好一个协议,读到什么什么的时候停,一般用对象流不好控制都用普通流的。
    2018-06-21 11:16:39
提问者 Jeremy936399 2018-06-20 11:54:32

这是造成我消息发送失败的原因吗?为什么会造成这样的后果啊?

提问者 Jeremy936399 2018-06-20 11:53:39

原因是什么呢?不这样写会产生什么问题呢?

Tender10 2018-06-20 11:51:40

TcpServer中的start()方法中,先在try..catch外定义一个空的ServerSocket对象,即

ServerSocket serverSocket = null;


问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
Android数据通信开发与应用2018版
  • 参与学习           人
  • 提交作业       147    份
  • 解答问题       687    个

本专题介绍了Android开发核心组件:广播、服务及全局应用。教会你如何使用AIDL、Thread、Socket、蓝牙解决进程线程间通信问题。利用Glide等实现异步加载及NDK原生代码开发。

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师