求大神指教= = 百度一下JAVA socket通信 例子 网上一大堆源码 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 客户端package cn.day05;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.Socket;import java.util.Scanner;/** * 客户端 * @author Dwyane_xu * */public class Client { //用于与服务器连接的Socket private Socket socket; public Client(){ try { /** * 实例化Socket,用于连接服务器 * SeverSocket * 参数1:服务器的ip地址 localhost表示本机 * 参数2: 服务端打开的端口 */ socket = new Socket("localhost", 8088); } catch (Exception e) { e.printStackTrace(); } } /** * 客户端启动方法 */ public void start(){ try { /** 启动用于接收服务端发送过来的信息的线程*/ GetServerInfoHandler handler = new GetServerInfoHandler(); Thread t = new Thread(handler); t.setDaemon(true); t.start(); /** * V2: * 从键盘获取用户输入的一行内容,然后 * 将其发送给服务器。并且这个操作可以 * 循环操作 */ //创建Scanner, 用于获取键盘输入放入内容 Scanner scanner = new Scanner(System.in); //java.io.OutputStream OutputStream out = socket.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8"); /** * 将字节输出流转换为缓冲字符输出流 */ PrintWriter writer = new PrintWriter(osw, true); while (true) { /** 从键盘读取一行内容,发送到服务端去*/ writer.println(scanner.nextLine()); } /** * 创建输入流,用于读取服务器发送过来的信息 */// InputStream in = // socket.getInputStream();// InputStreamReader isr = // new InputStreamReader(in);// BufferedReader reader = // new BufferedReader(isr);// // String str = reader.readLine();// System.out.println("Server say:"+str); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { //实例化一个客户端 Client client = new Client(); //启动客户端 client.start(); } /** * 该线程用于循环读取服务器发送过来的信息 * 并将其输出到控制台 * @author Dwyane_xu * */ private class GetServerInfoHandler implements Runnable{ public void run(){ try { InputStream in = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(in,"UTF-8"); BufferedReader reader = new BufferedReader(isr); /** 循环读取服务端发送的每一行内容*/ while (true) { //读取到后将其输出到客户端的控制台 String info = reader.readLine(); if(info == null){ //若读到空值,就停止该线程 break; } System.out.println(info); } } catch (Exception e) { } } }}服务端package cn.day05;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.util.Vector;import java.util.concurrent.BlockingDeque;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingDeque;/** * 服务端 * @author Dwyane_xu * */public class Server { //服务端的ServerSocket private ServerSocket server; //线程池 private ExecutorService threadPool; //存放所有客户端输出流的集合 private Vector<PrintWriter> allOut; //创建一个消息队列,保存所有带转发的信息 private BlockingDeque<String> msgQueue; public Server(){ try { /** * 创建服务端ServerSocket,并指定服务端口 * */ System.out.println("Start server....."); //初始化消息队列 msgQueue = new LinkedBlockingDeque<String>(); //启动消息转发线程 SendMsgToAllClientHandler sendHandler = new SendMsgToAllClientHandler(); Thread t = new Thread(sendHandler); t.start(); //初始化存放所有客户端输出流的集合 allOut = new Vector<PrintWriter>(); //初始化线程池 threadPool = Executors.newCachedThreadPool(); server = new ServerSocket(8088); System.out.println("Start server finish...."); } catch (Exception e) { e.printStackTrace(); } } /** * 将一个客户端输出流存入共享集合中 * @param writer */ /** * synchronized若修饰方法,那么当调用该方法时 * 锁的对象就是该方法所属的对象,这里就是main方法中 * 实例化的Server实例 * 当一个类中的几个方法都被synchronized修饰,那么 * 这几个方法是同步的 ,并且是互斥的。意思就是 * 多线程访问方法时,这几个方法选其一,只要有一个线程 * 执行了其中的一个方法,其他线程对剩下的方法都没有访问权限 */ public synchronized void addClientOut(PrintWriter writer){ allOut.add(writer); } /** * 将一个客户端的输出流从共享集合中删除 * @param writer */ public synchronized void removeClientOut(PrintWriter writer){ allOut.remove(writer); } /** * 将给定的信息转发给所有客户端 * @param msg */ public synchronized void sendMsgToAllClient(String msg){ /** 遍历所有客户端输出流*/ for(PrintWriter writer : allOut){ /** 将给定的字符串发给每一个客户端*/ writer.println(msg); } } /** * 服务端启动方法 */ public void start(){ try { //System.out.println("Wait client connect...."); /** * Socket accept() * 该方法是一个阻塞方法,直到一个客户端Socket * 连接,该方法才会返回,而返回的结果 * 就是这个客户端的Socket */ /** * V3 * 若想让服务端可以同时连接上不同客户端 * 那么我们就需要重复的调用accept()方法 * 这样服务端才能发现其他客户端的连接 * 但这里要是使用循环来监听客户端的连接,带来 * 的问题就是不能与连接上的客户端交互了。所以 * 需要启动线程来处理与连接上的客户端交互 */ while(true){ System.out.println("Wait client connect...."); Socket socket = server.accept(); System.out.println("A client connected!"); String hostName = socket.getInetAddress().getHostName(); String address = socket.getInetAddress().getHostAddress(); System.out.println("HostName:"+hostName); System.out.println("HostAddress:"+address); /** 创建线程,用于监听当前连接的客户端发送的信息*/ GetClientInfoHandler handler = new GetClientInfoHandler(socket); // Thread t = new Thread(handler);// t.start(); /** * 将任务指派给线程池,使其分配线程来 * 运行任务 */ threadPool.execute(handler); } /** * 服务端创建输出流,用于向客户端发信息 */// OutputStream out = // socket.getOutputStream();// PrintWriter writer = // new PrintWriter(out);// writer.println("Hello Client");// writer.flush(); } catch (Exception e) { } } public static void main(String[] args) { //实例化服务端对象 Server server = new Server(); //启动服务端 server.start(); } /** * 这个线程体用来在线程中 * 并发执行,与一个给定的客户端交互 * @author Dwyane_xu * */ private class GetClientInfoHandler implements Runnable{ //用来交互的客户端Socket private Socket socket; public GetClientInfoHandler(Socket socket){ this.socket = socket; } public void run() { //当前客户端输出流 PrintWriter writer = null; /** * 在线程中,获取该客户端的输入流,用于 * 读取客户端发送过来的数据 */ try { //java.io.InputStream InputStream in = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(in,"UTF-8"); BufferedReader reader = new BufferedReader(isr); /** * 创建用于向客户端发送信息的输出流 * 并存入共享集合 */ OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream(),"UTF-8"); writer = new PrintWriter(osw, true); addClientOut(writer); /** * V2 * 循环读取客户端发送过来的每一条数据 * 并输出到控制台 */ while(true){ /** * 读取客户端发送过来的一行字符串 */ String info = reader.readLine(); if(info == null){ throw new RuntimeException("Client connect exception"); }// System.out.println("Client say:"+ info); /** * 每当读取到该客户发送过来的信息 * 就转发个所有客户端 * * 这样存在缺陷。多线程同时转发可能会产生数据混乱的现象 * * 正确的做法是,将转发的数据存入消息队列,等待同一转发 */// sendMsgToAllClient(info); //向消息队列中添加一个信息 msgQueue.offer(info); } } catch (Exception e) { e.printStackTrace(); } finally{ try { //在和该客户端断开连接前,应该将该客户端的输出流从共享集合中删除 if(writer != null){ removeClientOut(writer); } //若和客户端连接存在异常,就关闭这个客户端连接 socket.close(); } catch (Exception e2) { e2.printStackTrace(); } } } } /** * 该线程用于周期性的从消息队列中读取信息 * 并转发给所有的客户端 * @author Dwyane_xu * */ private class SendMsgToAllClientHandler implements Runnable{ public void run(){ /** 遍历消息队列,将消息转发*/ while(true){ //从消息队列中取出第一条消息 String msg = msgQueue.poll(); if(msg != null){ //若有消息就转发 sendMsgToAllClient(msg); } else { //若没有消息,则休息 try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } } } } }} Socket -> RMI -> J2EE tomcat部署的web程序怎么越用越慢 求高手!!! java 聊天器 代码 求高手改!!! 关于jsp向servlet传值的问题 熟悉ssh2 的高手们请帮忙 读取ini hibernate model类的serialVersionUID 这到底是jdbc的问题还是数据库问题 头疼的问题,头发掉了一大把,求高手帮帮忙啊 jsp打印问题咨询 报表,急!!! 有关jdbc查询数据库的问题 有没有关于Excel表内,表间校验的程序,付费的也可以
package cn.day05;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 客户端
* @author Dwyane_xu
*
*/
public class Client {
//用于与服务器连接的Socket
private Socket socket;
public Client(){
try {
/**
* 实例化Socket,用于连接服务器
* SeverSocket
* 参数1:服务器的ip地址 localhost表示本机
* 参数2: 服务端打开的端口
*/
socket = new Socket("localhost", 8088);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 客户端启动方法
*/
public void start(){
try {
/** 启动用于接收服务端发送过来的信息的线程*/
GetServerInfoHandler handler =
new GetServerInfoHandler();
Thread t = new Thread(handler);
t.setDaemon(true);
t.start();
/**
* V2:
* 从键盘获取用户输入的一行内容,然后
* 将其发送给服务器。并且这个操作可以
* 循环操作
*/
//创建Scanner, 用于获取键盘输入放入内容
Scanner scanner = new Scanner(System.in);
//java.io.OutputStream
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw =
new OutputStreamWriter(out,"UTF-8");
/**
* 将字节输出流转换为缓冲字符输出流
*/
PrintWriter writer =
new PrintWriter(osw, true);
while (true) {
/** 从键盘读取一行内容,发送到服务端去*/
writer.println(scanner.nextLine());
}
/**
* 创建输入流,用于读取服务器发送过来的信息
*/
// InputStream in =
// socket.getInputStream();
// InputStreamReader isr =
// new InputStreamReader(in);
// BufferedReader reader =
// new BufferedReader(isr);
//
// String str = reader.readLine();
// System.out.println("Server say:"+str);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//实例化一个客户端
Client client = new Client();
//启动客户端
client.start();
}
/**
* 该线程用于循环读取服务器发送过来的信息
* 并将其输出到控制台
* @author Dwyane_xu
*
*/
private class GetServerInfoHandler implements Runnable{
public void run(){
try {
InputStream in = socket.getInputStream();
InputStreamReader isr =
new InputStreamReader(in,"UTF-8");
BufferedReader reader =
new BufferedReader(isr);
/** 循环读取服务端发送的每一行内容*/
while (true) {
//读取到后将其输出到客户端的控制台
String info = reader.readLine();
if(info == null){
//若读到空值,就停止该线程
break;
}
System.out.println(info);
}
} catch (Exception e) {
}
}
}
}服务端
package cn.day05;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;/**
* 服务端
* @author Dwyane_xu
*
*/
public class Server {
//服务端的ServerSocket
private ServerSocket server;
//线程池
private ExecutorService threadPool;
//存放所有客户端输出流的集合
private Vector<PrintWriter> allOut;
//创建一个消息队列,保存所有带转发的信息
private BlockingDeque<String> msgQueue;
public Server(){
try {
/**
* 创建服务端ServerSocket,并指定服务端口
*
*/
System.out.println("Start server.....");
//初始化消息队列
msgQueue = new LinkedBlockingDeque<String>();
//启动消息转发线程
SendMsgToAllClientHandler sendHandler =
new SendMsgToAllClientHandler();
Thread t = new Thread(sendHandler);
t.start();
//初始化存放所有客户端输出流的集合
allOut = new Vector<PrintWriter>();
//初始化线程池
threadPool = Executors.newCachedThreadPool();
server = new ServerSocket(8088);
System.out.println("Start server finish....");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 将一个客户端输出流存入共享集合中
* @param writer
*/
/**
* synchronized若修饰方法,那么当调用该方法时
* 锁的对象就是该方法所属的对象,这里就是main方法中
* 实例化的Server实例
* 当一个类中的几个方法都被synchronized修饰,那么
* 这几个方法是同步的 ,并且是互斥的。意思就是
* 多线程访问方法时,这几个方法选其一,只要有一个线程
* 执行了其中的一个方法,其他线程对剩下的方法都没有访问权限
*/
public synchronized void addClientOut(PrintWriter writer){
allOut.add(writer);
}
/**
* 将一个客户端的输出流从共享集合中删除
* @param writer
*/
public synchronized void removeClientOut(PrintWriter writer){
allOut.remove(writer);
}
/**
* 将给定的信息转发给所有客户端
* @param msg
*/
public synchronized void sendMsgToAllClient(String msg){
/** 遍历所有客户端输出流*/
for(PrintWriter writer : allOut){
/** 将给定的字符串发给每一个客户端*/
writer.println(msg);
}
}
/**
* 服务端启动方法
*/
public void start(){
try {
//System.out.println("Wait client connect....");
/**
* Socket accept()
* 该方法是一个阻塞方法,直到一个客户端Socket
* 连接,该方法才会返回,而返回的结果
* 就是这个客户端的Socket
*/
/**
* V3
* 若想让服务端可以同时连接上不同客户端
* 那么我们就需要重复的调用accept()方法
* 这样服务端才能发现其他客户端的连接
* 但这里要是使用循环来监听客户端的连接,带来
* 的问题就是不能与连接上的客户端交互了。所以
* 需要启动线程来处理与连接上的客户端交互
*/
while(true){
System.out.println("Wait client connect....");
Socket socket = server.accept();
System.out.println("A client connected!");
String hostName = socket.getInetAddress().getHostName();
String address = socket.getInetAddress().getHostAddress();
System.out.println("HostName:"+hostName);
System.out.println("HostAddress:"+address);
/** 创建线程,用于监听当前连接的客户端发送的信息*/
GetClientInfoHandler handler =
new GetClientInfoHandler(socket);
// Thread t = new Thread(handler);
// t.start();
/**
* 将任务指派给线程池,使其分配线程来
* 运行任务
*/
threadPool.execute(handler);
}
/**
* 服务端创建输出流,用于向客户端发信息
*/
// OutputStream out =
// socket.getOutputStream();
// PrintWriter writer =
// new PrintWriter(out);
// writer.println("Hello Client");
// writer.flush();
} catch (Exception e) {
}
}
public static void main(String[] args) {
//实例化服务端对象
Server server = new Server();
//启动服务端
server.start();
}
/**
* 这个线程体用来在线程中
* 并发执行,与一个给定的客户端交互
* @author Dwyane_xu
*
*/
private class GetClientInfoHandler implements Runnable{ //用来交互的客户端Socket
private Socket socket;
public GetClientInfoHandler(Socket socket){
this.socket = socket;
}
public void run() {
//当前客户端输出流
PrintWriter writer = null;
/**
* 在线程中,获取该客户端的输入流,用于
* 读取客户端发送过来的数据
*/
try {
//java.io.InputStream
InputStream in = socket.getInputStream();
InputStreamReader isr =
new InputStreamReader(in,"UTF-8");
BufferedReader reader =
new BufferedReader(isr);
/**
* 创建用于向客户端发送信息的输出流
* 并存入共享集合
*/
OutputStreamWriter osw =
new OutputStreamWriter(socket.getOutputStream(),"UTF-8");
writer = new PrintWriter(osw, true);
addClientOut(writer);
/**
* V2
* 循环读取客户端发送过来的每一条数据
* 并输出到控制台
*/
while(true){
/**
* 读取客户端发送过来的一行字符串
*/
String info = reader.readLine();
if(info == null){
throw new RuntimeException("Client connect exception");
}
// System.out.println("Client say:"+ info);
/**
* 每当读取到该客户发送过来的信息
* 就转发个所有客户端
*
* 这样存在缺陷。多线程同时转发可能会产生数据混乱的现象
*
* 正确的做法是,将转发的数据存入消息队列,等待同一转发
*/
// sendMsgToAllClient(info);
//向消息队列中添加一个信息
msgQueue.offer(info);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
//在和该客户端断开连接前,应该将该客户端的输出流从共享集合中删除
if(writer != null){
removeClientOut(writer);
}
//若和客户端连接存在异常,就关闭这个客户端连接
socket.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
/**
* 该线程用于周期性的从消息队列中读取信息
* 并转发给所有的客户端
* @author Dwyane_xu
*
*/
private class SendMsgToAllClientHandler implements Runnable{
public void run(){
/** 遍历消息队列,将消息转发*/
while(true){
//从消息队列中取出第一条消息
String msg = msgQueue.poll();
if(msg != null){
//若有消息就转发
sendMsgToAllClient(msg);
} else {
//若没有消息,则休息
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}