socket传递对象的几点问题

本文介绍如何使用Java的Socket编程实现对象的远程传输,并通过客户端和服务端的实例代码演示了具体的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做个聊天的小项目,也比较忙,就没什么时间发博客了。今天早上是抽空出来发的,好吧,废话不多说。

由于做聊天这样的东西,肯定要用到socket、multyThread这类东西,而利用socket进行数据的传输无疑是必须的。java为我们提供了强大的IO流,利用socket,基本上可以传送任何类型的数据了。那么我在这里选择了ObjectOuputStream和ObjectInputStream,因为这两者可以传递对象。事不宜迟,先来个简单的对象传递的例子。

1、首先是一个简单的类,用于创建对象。

import java.io.Serializable;

public class User implements Serializable{	//实现序列号接口,但不需要实现任何方法
	
	private String id;
	private String name;
	private String psw;
	private String gender;
	private String mail;
	
	public User() {
		super();
	}

	public User(String id, String name, String psw, String gender, String mail) {
		super();
		this.id = id;
		this.name = name;
		this.psw = psw;
		this.gender = gender;
		this.mail = mail;
	}

	public String getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPsw() {
		return psw;
	}

	public void setPsw(String psw) {
		this.psw = psw;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public void setMail(String mail) {
		this.mail = mail;
	}
	
	public String getMail() {
		return this.mail;
	}

	public String toString() {
		return "User [gender=" + gender + ", id=" + id + ", mail=" + mail
				+ ", name=" + name + ", psw=" + psw + "]";
	}
	
}

2、接下来是客户端部分的代码

package test.socket;

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;
import java.net.UnknownHostException;

public class MyClient {
	
	public static void main(String[] args) {
		
		Socket socket = null;		
		OutputStream os = null;
		ObjectOutputStream oos = null;
		InputStream is = null;
		ObjectInputStream ois = null;

		try {
			socket = new Socket("localhost", 50000);	//连接服务器
			//获得输出流
			os = socket.getOutputStream();				//客户端部分应该先初始化输出流
			oos = new ObjectOutputStream(os);
			//获得输入流
			is = socket.getInputStream();				
			ois = new ObjectInputStream(new BufferedInputStream(is));
			//初始化一个user对象,用于传递
			User user = new User("10000", "小明", "123456", "男", "229047554@qq.com");
			System.out.println("没送到服务器之前:" + user.toString());
			//将user送往服务器端
			oos.writeObject(user);
			oos.flush();
			//得到服务器送来的user
			user = (User) ois.readObject();
			System.out.println("送往服务器之后:" + user.toString());
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				
				if(socket != null)
					socket.close();
				if(os != null)
					os.close();
				if(oos != null)
					oos.close();
				if(is != null)
					is.close();
				if(ois != null)
					ois.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

3、接下来是服务器端代码

package test.socket;

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.ServerSocket;
import java.net.Socket;

import com.scau.model.User;

public class MyServer {
	
	public static void main(String[] args) {
		
		ServerSocket serverSocket = null;
		Socket clientSocket = null;
		ObjectInputStream ois = null;
		InputStream is = null;
		OutputStream os = null;
		ObjectOutputStream oos = null;
		
		try {  
			serverSocket = new ServerSocket(50000); 
			
            while(true) {  
            	
            	clientSocket = serverSocket.accept();
            	//获得输入流  
                is = clientSocket.getInputStream();        //服务端部分应该先初始化输入流  
                ois = new ObjectInputStream(new BufferedInputStream(is));
                //获得输出流  
                os = clientSocket.getOutputStream();                
                oos = new ObjectOutputStream(os);  
                

                User user = (User) ois.readObject();  
                user.setName("小红");  
                user.setGender("女");  
                oos.writeObject(user);  
                oos.flush();  
            }  
        } catch (IOException e) {  
            e.printStackTrace();  
        } catch (ClassNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } finally {  
            try {  
                if(serverSocket != null) {  
                    serverSocket.close();  
                }  
                if(clientSocket != null)  
                    clientSocket.close();  
                if(os != null)  
                    os.close();  
                if(oos != null)  
                    oos.close();  
                if(is != null)  
                    is.close();  
                if(ois != null)  
                    ois.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
	}
}


其实代码是比较简单的。。。就不分析了,我也做了几点注释,在这里说说我遇到的几点问题吧。

1、客户端的代码在初始化对象流时,必须先初始化输出流,你可以将客户端的代码修改下,即把输出流放在输入流的下面然后在运行程序,你会发现,程序卡死了。其原因我也不是很清楚,但如果你一定要先初始化输入流,那也是可以的,那么你就在服务器端先初始化输出流,这样就没有问题了。

1、修正:其实只要两端都不先初始化输入流就行的,又重新实验了一下。

2、对于ObjectOutputStream和ObjectInputStream这两种流,是死锁流,也就是说在同一个线程里,你不能new 两个ObjectOutputStream或者两个ObjectInputStream出来,如果你这样做了,那么恭喜你,程序将会抛出异常java.net.SocketException: Connection reset或者卡死,反正各种问题。。。

3、对于多线程的socket,尤其是你需要保存socket,比如说:在做聊天功能的时候,你经常需要将socket保存到动态数组中ArrayList或者LinkedList,但是你又之前new了一个ObjectOutputStream,那么你再拿出这个socket进行传送数据时,你就不能再重新new一个ObjectOutputStream了,解决的方法有两个:第一,你可以再重新建立一个全新的socket,然后保存这个socket,这样你就可以new ObjectOutputStream了。第二:你也可以在保存socket的时候,将相应ObjectOutputStream对象保存下来,即也保存到一个动态数组中,这样需要使用的时候直接用就行了。。。

好吧,总结写到这里了,如有什么错误的地方,还请指正。联系:229047554@qq.com


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值