posts - 310, comments - 6939, trackbacks - 0, articles - 3
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

多线程Java Socket编程示例

Posted on 2007-10-15 12:37 诗特林 阅读(92446) 评论(25)  编辑  收藏 所属分类: Socket
                                                 多线程Java Socket编程示例

这篇做为学习孙卫琴<<Java网络编程精解>>的学习笔记吧.其中采用Java 5的ExecutorService来进行线程池的方式实现多线程,模拟客户端多用户向同一服务器端发送请求.

1.服务端
package sterning;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.*;
import java.util.concurrent.*;

public class MultiThreadServer {
    
private int port=8821;
    
private ServerSocket serverSocket;
    
private ExecutorService executorService;//线程池
    private final int POOL_SIZE=10;//单个CPU线程池大小
    
    
public MultiThreadServer() throws IOException{
        serverSocket
=new ServerSocket(port);
        
//Runtime的availableProcessor()方法返回当前系统的CPU数目.
        executorService=Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_SIZE);
        System.out.println(
"服务器启动");
    }

    
    
public void service(){
        
while(true){
            Socket socket
=null;
            
try {
                
//接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接
                socket=serverSocket.accept();
                executorService.execute(
new Handler(socket));
                
            }
 catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

    
    
public static void main(String[] args) throws IOException {
        
new MultiThreadServer().service();
    }


}


class Handler implements Runnable{
    
private Socket socket;
    
public Handler(Socket socket){
        
this.socket=socket;
    }

    
private PrintWriter getWriter(Socket socket) throws IOException{
        OutputStream socketOut
=socket.getOutputStream();
        
return new PrintWriter(socketOut,true);
    }

    
private BufferedReader getReader(Socket socket) throws IOException{
        InputStream socketIn
=socket.getInputStream();
        
return new BufferedReader(new InputStreamReader(socketIn));
    }

    
public String echo(String msg){
        
return "echo:"+msg;
    }

    
public void run(){
        
try {
            System.out.println(
"New connection accepted "+socket.getInetAddress()+":"+socket.getPort());
            BufferedReader br
=getReader(socket);
            PrintWriter pw
=getWriter(socket);
            String msg
=null;
            
while((msg=br.readLine())!=null){
                System.out.println(msg);
                pw.println(echo(msg));
                
if(msg.equals("bye"))
                    
break;
            }

        }
 catch (IOException e) {
            e.printStackTrace();
        }
finally{
            
try {
                
if(socket!=null)
                    socket.close();
            }
 catch (IOException e) {
                e.printStackTrace();
            }

        }

    }

}

2.客户端
package sterning;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MultiThreadClient {
    
    
public static void main(String[] args) {
        
int numTasks = 10;
        
        ExecutorService exec 
= Executors.newCachedThreadPool();

        
for (int i = 0; i < numTasks; i++{
            exec.execute(createTask(i));
        }


    }


    
// 定义一个简单的任务
    private static Runnable createTask(final int taskID) {
        
return new Runnable() {
            
private Socket socket = null;
            
private int port=8821;

            
public void run() {
                System.out.println(
"Task " + taskID + ":start");
                
try {                    
                    socket 
= new Socket("localhost", port);
                    
// 发送关闭命令
                    OutputStream socketOut = socket.getOutputStream();
                    socketOut.write(
"shutdown\r\n".getBytes());

                    
// 接收服务器的反馈
                    BufferedReader br = new BufferedReader(
                            
new InputStreamReader(socket.getInputStream()));
                    String msg 
= null;
                    
while ((msg = br.readLine()) != null)
                        System.out.println(msg);
                }
 catch (IOException e) {                    
                    e.printStackTrace();
                }

            }


        }
;
    }

}


从而实现了多个客户端向服务器端发送请求,服务器端采用多线程的方式来处理的情况.再结合我之前的例子---Java基于Socket文件传输示例,就可以实现多线程文件的传输了

评论

# re: 多线程Java Socket编程示例  回复  更多评论   

2007-11-10 14:25 by xiongzeng
请问作者:
可不可以利用服务端主动发信?

# re: 多线程Java Socket编程示例  回复  更多评论   

2007-12-07 13:12 by qifen
膏药帖~~

# re: 多线程Java Socket编程示例  回复  更多评论   

2008-01-07 22:19 by java综合网
很好!不错!

# re: 多线程Java Socket编程示例  回复  更多评论   

2008-03-14 11:36 by fgfdg
dgdfggfdgdf

# re: 多线程Java Socket编程示例  回复  更多评论   

2008-05-28 17:14 by 钟侥
我也是参照孙的书,可是运行不能得到正确的结果!很是郁闷啊
[code]
package com.zz.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class EchoServer {

private int port = 8000;
private ServerSocket ss;

public EchoServer() throws IOException {
ss = new ServerSocket(port);
System.out.println("server is starting....");
}

private String echoString(String msg){
return "echo:" + msg;
}
public static void main(String[] args) {
try {
new EchoServer().service();
} catch (IOException e) {
e.printStackTrace();
}
}

private void service(){
while(true){
Socket s = null;
try{
s = ss.accept();
System.out.println("a client is coming......");
BufferedReader br = this.getReader(s);
PrintWriter pw = this.getWriter(s);
String msg = null;
while((msg = br.readLine()) != null){
System.out.println(msg);
pw.println(this.echoString(msg)+"\n");
pw.flush();
if(msg.equals("bye")) break;
}
}catch(IOException e ){

}
}
}

private PrintWriter getWriter(Socket s) throws IOException {
return new PrintWriter(s.getOutputStream());
}

private BufferedReader getReader(Socket s) throws IOException {
return new BufferedReader(new InputStreamReader(s.getInputStream()));
}

}



[/code]

# re: 多线程Java Socket编程示例  回复  更多评论   

2008-05-28 17:15 by 钟侥
package com.zz.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class EchoClient {
private String host = "localhost";
private int port = 8000;
private Socket socket;

private EchoClient() throws IOException {
socket = new Socket(host, port);
}

public void talk() throws IOException {
try {
BufferedReader br = getReader(socket);
PrintWriter pw = getWriter(socket);
BufferedReader localReader = new BufferedReader(
new InputStreamReader(System.in));
String msg = null;
while ((msg = localReader.readLine())!= null) {
pw.println(msg+"\n");
pw.flush();
System.out.println(br.readLine());
if (msg.equals("bye"))
break;
}
} catch (IOException e) {
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

private PrintWriter getWriter(Socket s) throws IOException {
return new PrintWriter(s.getOutputStream());
}

private BufferedReader getReader(Socket s) throws IOException {
return new BufferedReader(new InputStreamReader(s.getInputStream()));
}

/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
new EchoClient().talk();

}

}

# re: 多线程Java Socket编程示例  回复  更多评论   

2008-06-16 23:04 by 有猫相伴的日子
这个代码有很多问题,如请求处理,怎么封装请求对象,把请求对象放一队列

从服务器端怎么发消息到客户端.....

# re: 多线程Java Socket编程示例  回复  更多评论   

2009-04-27 10:22 by fei
貌似整体思想可以,但是,程序的问题就比较多了...

# re: 多线程Java Socket编程示例[未登录]  回复  更多评论   

2009-05-07 15:38 by jh
第三方杀毒

# re: 多线程Java Socket编程示例  回复  更多评论   

2009-05-07 17:14 by OverKill
如果多个线程对同一资源进行读取,能保证资源的原子性吗?应该对资源加锁

# re: 多线程Java Socket编程示例  回复  更多评论   

2009-05-17 15:52 by 点水点点
正找这样的文章 多谢

# re: 多线程Java Socket编程示例[未登录]  回复  更多评论   

2009-08-23 19:12 by Mark
如何设定超时的问题呢?

# re: 多线程Java Socket编程示例  回复  更多评论   

2010-05-09 13:48 by 诗特林fans
我是java网络编程的初学者很想加 诗特林 为好友向你请教些问题。我的qq826463574

# re: 多线程Java Socket编程示例  回复  更多评论   

2010-05-09 14:05 by 诗特林fans
服务器端:
public class MultiThreadServer {
private int port=8821;
private ServerSocket serverSocket;
private ExecutorService executorService;//线程池
private final int POOL_SIZE=10;//单个CPU线程池大小

public MultiThreadServer() throws IOException{
serverSocket=new ServerSocket(port);
//Runtime的availableProcessor()方法返回当前系统的CPU数目.
executorService=Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_SIZE);
System.out.println("服务器启动");
}

public void service(){
while(true){
Socket socket=null;
try {
//接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接
socket=serverSocket.accept();
executorService.execute(new Handler(socket));

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

public static void main(String[] args) throws IOException {
new MultiThreadServer().service();
}

}

class Handler implements Runnable{
private Socket socket;
public Handler(Socket socket){
this.socket=socket;
}
/*private DataOutputStream dos(Socket socket) throws IOException{
OutputStream socketOut=socket.getOutputStream();
return new DataOutputStream(socketOut);
}
private DataInputStream dis(Socket socket) throws IOException{
InputStream socketIn=socket.getInputStream();
return new DataInputStream(socketIn);
}*/

public void run(){
try {
System.out.println("New connection accepted "+socket.getInetAddress()+":"+socket.getPort());
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);

InputStream is = socket.getInputStream( );
DataInputStream dis=new DataInputStream(is);
new myserverread(dis).start();
new myserverwite(dos).start();


} catch (IOException e) {
e.printStackTrace();
}/*finally{
try {
if(socket!=null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}*/
}
}
class myserverread extends Thread{
private DataInputStream dis;
public myserverread (DataInputStream dis){
this.dis=dis;
}
public void run(){
String info;
try{
while(true)
{
info=dis.readUTF();
System.out.println("对方说"+info);
if (info.equals("bye")){
System.out.println("对方下线,程序退出");
System.exit(0);}
}
}
catch (Exception e){e.getStackTrace();}

}
}

class myserverwite extends Thread{
private DataOutputStream dos;
public myserverwite (DataOutputStream dos){
this.dos=dos;
}
public void run(){
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String info;
try{
while(true)
{
info=br.readLine();
dos.writeUTF(info);
if (info.equals("bye")){
System.out.println("自己下线,程序退出");
System.exit(0);}
}
}
catch (Exception e){e.getStackTrace();}

}
}



# re: 多线程Java Socket编程示例  回复  更多评论   

2010-05-09 14:06 by 诗特林fans
客户端:


import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;



public class MultiThreadClient {

public static void main(String[] args) {
int ID=Info.i;

ExecutorService exec = Executors.newCachedThreadPool();

/* for (int i = 0; i < numTasks; i++) {
exec.execute(createTask(i));
}
*/
System.out.println("客户端线程"+ID+"已启动~~");
exec.execute(createTask(ID));
Info.i=ID++;

}

// 定义一个简单的任务
private static Runnable createTask(int taskID) {
// this.taskID=taskID;
return new Runnable() {
private Socket socket = null;
private int port=8821;

public void run() {

// System.out.println("Task " + taskID + ":start");
try {
socket = new Socket("localhost", port);
// 发送关闭命令
InputStream is = socket.getInputStream( );
DataInputStream dis=new DataInputStream(is);

OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);

new myclientread(dis).start();
new myclientwite(dos).start();

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

};
}
}
class myclientread extends Thread{
private DataInputStream dis;
public myclientread (DataInputStream dis){
this.dis=dis;
}
public void run(){
String info;
try{
while(true)
{
info=dis.readUTF();
System.out.println("对方说"+info);
if (info.equals("bye")){
System.out.println("对方下线,程序退出");
System.exit(0);}
}
}
catch (Exception e){e.getStackTrace();}

}
}

class myclientwite extends Thread{
private DataOutputStream dos;
public myclientwite (DataOutputStream dos){
this.dos=dos;
}
public void run(){
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String info;
try{
while(true)
{
info=br.readLine();
dos.writeUTF(info);
if (info.equals("bye")){
System.out.println("自己下线,程序退出");
System.exit(0);}
}
}
catch (Exception e){}

}
}

这个程序我想实现多用户与服务器的连接交互问题,但是能过连接上但是不能实现交互,这是为什么呢?我是java网络编程初学者谢谢您的指教急待您的回复!

# re: 多线程Java Socket编程示例[未登录]  回复  更多评论   

2010-08-19 16:52 by zheng
学习了

# re: 多线程Java Socket编程示例  回复  更多评论   

2012-04-01 16:54 by 安安
你好,这样不会出现中文乱码吗?

# re: 多线程Java Socket编程示例[未登录]  回复  更多评论   

2013-06-03 20:55 by 孙杰
求 超市收银系统 用XML Socket 和多线程 做的 有的发我邮箱 769566815@qq.com

# re: 多线程Java Socket编程示例[未登录]  回复  更多评论   

2013-06-03 20:58 by 孙杰
跪求 急用 6月5号交上去

# re: 多线程Java Socket编程示例  回复  更多评论   

2014-04-30 10:37 by 126
@钟侥
while(true){
Socket s = null;

每次s都是null

# re: 多线程Java Socket编程示例  回复  更多评论   

2014-04-30 10:42 by 126
看错了,

s = ss.accept();

你那个代码变量名太差了吧!看都看不清!

# re: 多线程Java Socket编程示例  回复  更多评论   

2014-05-22 16:29 by momo128
请问您知不知道哪里有socket的学习视频啊?因为手头资料实在有限,有好多不懂的地方。如果有的话请发到我的邮箱960696649@qq.com,麻烦您了~

# re: 多线程Java Socket编程示例  回复  更多评论   

2014-07-30 22:02 by 月小升
很不错的socket教程

# re: 多线程Java Socket编程示例  回复  更多评论   

2014-11-18 16:42 by 一个好人
@有猫相伴的日子
项目中正打算使用这段代码的,看你的品论才发现 确实没有用到队列,如果并发数量超过线程数会出现什么情况?

只有注册用户登录后才能发表评论。


网站导航: