黑马程序员技术交流社区
标题:
一个自己封装的TCP通讯类,大家看看如何
[打印本页]
作者:
袁啟雄x
时间:
2014-4-11 18:00
标题:
一个自己封装的TCP通讯类,大家看看如何
首先是底层类
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class MySocket {
//内置连接对象
private Socket socket ;
//对象发送流,发送的对象必须序列化
private ObjectOutputStream oos;
//对象接收流
private ObjectInputStream ois;
//重载构造函数 , 这个主动连接,提供IP地址和端口
public MySocket(String ip , int port){
try {
//初始化对象,并连接到指定的IP地址和端口
socket = new Socket(ip, port);
//获取输入流.
ois = new ObjectInputStream(socket.getInputStream());
//获取输出流
oos = new ObjectOutputStream(socket.getOutputStream());
} catch (Exception e) {
//当发生异常调用关闭连接函数
close();
}
}
//重载构造函数 , 这个被动连接,通过ServerSocket监听获取socket对象进行
public MySocket(Socket socket){
this.socket = socket;
try {
//因为主动连接哪里是先获取输入流,这里必须先获取输出流,不然会卡死
oos = new ObjectOutputStream(socket.getOutputStream());
//然后获取输入流
ois = new ObjectInputStream(socket.getInputStream());
} catch (Exception e) {
//当发生异常调用关闭连接函数
close();
}
}
public boolean write(Object msg){
//若输出流对象为NULL,返回FALSE
if(oos==null) return false;
try {
//进行发送对象操作
oos.writeObject(msg);
//成功返回TRUE
return true;
} catch (Exception e) {
//发送失败调用关闭连接函数
close();
//返回FALSE
return false;
}
}
public Object read(){
//若输入流对象为NULL,返回NULL
if(ois==null) return null;
try {
//闭塞方法,若要即时通讯,请用多线程调用此函数 , 进行读消息
return ois.readObject();
} catch (Exception e) {
//接收失败调用关闭连接函数
close();
//返回NULL
return null;
}
}
//关闭连接
public boolean close(){
if(socket!=null){
try {
socket.close();
oos.close() ;
ois.close() ;
socket = null ;
oos = null ;
ois = null ;
return true;
} catch (Exception e) {
return false;
}
} else return false;
}
}
复制代码
然后就是上层的服务端,用于测试的
import java.net.ServerSocket;
import org.thisdk.conn.MyMsg;
import org.thisdk.conn.MySocket;
public class MyServer {
public static void main(String[] args) throws Exception {
//监听本地特定端口
ServerSocket ss = new ServerSocket(3866);
//开始监听并把连接进来的客户端生成的socket对象传递到MySocket的重载构造函数
MySocket tc = new MySocket(ss.accept());
//读取消息
MyMsg msg =(MyMsg)tc.read();
//打印读取的消息
System.out.println(msg.getMsg());
//定义要发送的消息
msg.setMsg("这是服务端发送的消息!");
//发送消息
tc.write(msg);
//循环接收客户端发送的消息
do {
//读取消息
msg =(MyMsg)tc.read();
//检查读取到的内容是否正常
if(msg==null) System.out.println("客户端关闭连接...");
//正常就打印内容
else System.out.println(msg.getMsg());
} while (msg!=null);
}
}
复制代码
再就是用于测试客户端
import org.thisdk.conn.MyMsg;
import org.thisdk.conn.MySocket;
public class MyClient {
public static void main(String[] args) {
//新建对象并连接
MySocket tc = new MySocket("127.0.0.1", 3866);
//定义要发送的消息
MyMsg msg = new MyMsg("这是客户端发送的消息");
//发送消息
tc.write(msg);
//读取消息
msg = (MyMsg) tc.read();
//查看读取到的内容
System.out.println(msg.getMsg());
//继续发送
tc.write(new MyMsg("tttttttttt"));
tc.write(new MyMsg("qqqqqqqqqq"));
tc.write(new MyMsg("yyyyyyyyyy"));
//关闭连接
tc.close();
}
}
复制代码
工具类,用于通讯的
import java.io.Serializable;
//这是测试对象,必须实现Serializable接口以序列化
public class MyMsg implements Serializable{
private static final long serialVersionUID = 3866L;
private String msg ;
public MyMsg(String msg){
this.msg = msg ;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
复制代码
思路是这样的.通过封装好Socket的连接等相应操作,然后在客户端直接调用封装好的操作,来达到简单操作.
因为是发送对象的.这样做我觉得好处在于,无论要发送什么,我都可以直接把要发送的东西封装在类里面,无论是文字,图片,甚至是其他自定义的类对象都行.只要定义好相应的通讯类即可.有什么建议的可以提出来,大家共同进步
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2