急急急!求大神帮忙啊

chengxuyuandoudou 2014-05-05 09:49:19
关于socket出现乱码问题
服务端代码:package test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class Server {
private ServerSocket serverSocket;

//线程池
private ExecutorService threadPool;

/**
* 双缓冲队列,用于保存所有客户端发送到服务器的信息
*/
private BlockingQueue<String> msgQueue;

/**
* 创建一个集合,用于保存所有客户端的输出流
* 因为多线程要访问这个集合,它应该是个安全的
*/
private Vector<PrintWriter> allOut =
new Vector<PrintWriter>();

public Server(){
try {
/**
* 打开服务端Socket时要捕获异常
* 最常见的这里出现的问题就是申请的端口号已经被
* 其他程序占用了。
* 错误信息中会出现 JVM_BIND 的信息。
*
* 这里的端口号不是真正意义上的端口,是一个抽象的
* 概念
* 我们可以理解为是我们的程序在操作系统上想使用网络
* 通信,而相操作系统注册的一个编号。
* 将来外界发送信息过来时,操作系统就根据信息要请求
* 的端口号,将这段信息交给我们的程序去处理。
*/
serverSocket = new ServerSocket(8087);
//创建线程池
threadPool = Executors.newCachedThreadPool();
// threadPool = Executors.newFixedThreadPool(20);
//初始化双缓冲队列
msgQueue = new LinkedBlockingQueue<String>();

//启动用于转发信息的线程
SendInfoToCliendHandler handler =
new SendInfoToCliendHandler();
Thread thread = new Thread(handler);
thread.start();

System.out.println("服务器启动了");
} catch (IOException e) {
e.printStackTrace();
}
}

//开始服务
public void start(){
try {
/**
* Socket accept()
* 该方法用于在8088端口进行等待,等待客户端的连接
* 当一个客户端通过ip与端口号连接上时,会返回这个
* 客户端的Socket与其开始通信。
* 这个方法是一个阻塞方法,若客户端一直不连接,该
* 方法就一直不能执行完毕。
*/
while(true){
System.out.println("等待客户端的连接...");
Socket socket = serverSocket.accept();
System.out.println("一个客户端连接了。");

/**
* 一个客户端连接了,就将这个客户端的输出流
* 放入共享集合
*/
allOut.add(
new PrintWriter(
socket.getOutputStream()
)
);

/**
* 启动一个线程,用于和刚连上的这个客户端交流
*/
Handler handler = new Handler(socket);
// Thread t = new Thread(handler);
// t.start();
/**
* 将并发执行的任务交给线程池,让线程池分配
* 空线程来运行。线程池在运行完任务后会自动
* 回收线程等待再次分配任务去执行。
*/
threadPool.execute(handler);
}

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

public static void main(String[] args) {
/**
* 因为构造方法中创建了ServerSocket
* 所以这里相当于就启动了服务端
*/
Server server = new Server();
/**
* 调用start方法后,会监听ServerSocket注册的端口号
* 8088,等待客户端的连接。
*/
server.start();
}

/**
* 定义一个线程体
* 该线程体用来并发操作
* 每一个线程用来与一个客户端交流,获取客户端发送过来的
* 信息
* @author admin
*
*/
private class Handler implements Runnable{
/**
* 当前线程要处理的客户端Socket
*/
private Socket client;

/**
* 通过构造方法,将客户端Socket传进来
* @param client
*/
public Handler(Socket client){
this.client = client;
}
@Override
public void run() {
try {
/**
* 通过刚刚连接的客户端的Socket获取输入流
* 用于读取客户端发送过来的信息
*/
InputStream in = client.getInputStream();
/**
* 将字节输入流转换为缓冲字符输入流,以便于我们
* 以行为单位读取字符串
*/
InputStreamReader ir
= new InputStreamReader(in);

BufferedReader reader
= new BufferedReader(ir);
String info = null;
//循环读取客户端发送过来的信息
while((info = reader.readLine())!= null){
// System.out.println("客户端说:"+info);
// //将这个客户端发送的信息转发给所有客户端
// for(int i =0;i<allOut.size();i++){
// allOut.get(i).println(info);
// allOut.get(i).flush();
// }
/**
* 当读取到客户端发送过来的信息后,就将这条
* 信息放入双缓冲队列,等待被转发
*/
msgQueue.offer(info);
}
} catch (Exception e) {
e.printStackTrace();
}

}

}
/**
* 该线程只有一个实例,用于循环读取双缓冲队列
* 中的信息,并转发给所有客户端
* @author admin
*
*/
private class SendInfoToCliendHandler
implements Runnable{

@Override
public void run() {
try {
//1 循环读取双缓冲队列
while(true){
int size = msgQueue.size();
for(int i=0;i<size;i++){
//2从队列中获取一条信息
String info = msgQueue.poll();
//3转发给所有客户端
for(PrintWriter writer:allOut){
writer.println(info);
writer.flush();
}
}
//每次将所有信息都转发后停顿一下
Thread.sleep(500);
}


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

}

}
}
客户端的:
package test;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class Client {
private Socket socket;
public String sin = "你好";
public Client(){
try {
socket = new Socket("localhost",8087);

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

public void start(){
try {
GetServerInfoHandler handler =
new GetServerInfoHandler(socket);
Thread thread = new Thread(handler);
thread.start();
OutputStream out = socket.getOutputStream();
PrintWriter writer = new PrintWriter(out);
// BufferedReader reader =
// new BufferedReader(
// new InputStreamReader(
// sin,"UTF-8"
// )
// );
/**
* 循环按行读取键盘输入的信息,并通过输出流
* 写到服务端去
*/
String info = null;
//while((info = reader.readLine())!=null){
writer.println(sin.getBytes("utf-8"));

writer.flush();//清空缓冲区,将字符串写到服务端

// }


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

public static void main(String[] args) {
Client client = new Client();
client.start();
}
private class GetServerInfoHandler implements Runnable{

private Socket socket;

public GetServerInfoHandler(Socket socket){
this.socket = socket;
}

@Override
public void run() {
try {
InputStream in = socket.getInputStream();
//将字节流转换为字符流
BufferedReader reader =
new BufferedReader(
new InputStreamReader(
in,"utf-8"
)
);
String info = null;
while((info = reader.readLine()) != null){
System.out.println(info);
}

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

}

}
}
发送你好 为什么客户端返回的是 [B@15ded0fd 这种东西
...全文
167 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
极客架构 2014-05-05
  • 打赏
  • 举报
回复
你返回的是对象了 ,需要 转成字符串
linhua11 2014-05-05
  • 打赏
  • 举报
回复
我猜是new InputStreamReader( in,"utf-8" ),utf-8 没中文支持吧
linhua11 2014-05-05
  • 打赏
  • 举报
回复
不好意思,回答错了,我自己试了下,你犯了个小错误. writer.println(sin.getBytes("utf-8")); 改成 writer.println(sin);

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧