Java Socket 编程——多线程网络聊天程序

本文作者:longlongago     博客地址:http://blog.csdn.net/longlongago2000

用java进行网络编程确实很方便,很容易上手。这几天用java进行socket编程,收获不少。

首先,进行服务端的编程,作为服务端,编程主要按下面几个步骤进行:

//  1. 创建socket
            ServerSocket ss  =   new  ServerSocket(PortNumber);
            Socket s 
=  ss.accept();  // 监听器,产生阻塞,直到有连接才停止阻塞。 

            
//  2. 打开输入流、输出流
            OutputStream os  =  s.getOutputStream();
            BufferedOutputStream bos 
=   new  BufferedOutputStream(os);
            InputStream is 
=  s.getInputStream(); 

            
//  3. 根据一定的协议读写数据
            
//  服务器 --> 客户
//             os.write("Hello,I am Server!".getBytes());
            bos.write( " Hello,I am Server! " .getBytes());
            bos.flush(); 
// 注意!! 

            
//  服务器 <-- 客户
             byte [] buf  =   new   byte [ 100 ];
            
int  len  =  is.read(buf);
            System.out.println(
new  String(buf,  0 , len)); 

            
//  4. 关系流和Socket
//             os.close();
            bos.close();
            is.close();
            s.close();
            ss.close(); 

 

作为客户端则分为下面几个步骤,其实和服务端差不多,只是少了用ServerSocket进行监听。

//  1. 创建socket
            Socket s  =   new  Socket(InetAddress.getByName( " localhost " ),
                    PortNumber);
            
//  2. 打开输入流、输出流
            OutputStream os  =  s.getOutputStream();
            InputStream is 
=  s.getInputStream(); 

            
//  3. 根据一定的协议读写数据
            
//  服务器 --> 客户
             byte [] buf  =   new   byte [ 100 ];
            
int  len  =  is.read(buf);
            System.out.println(
new  String(buf,  0 , len));
            
//  服务器 <-- 客户
            os.write( " Hello,I am Client! " .getBytes()); 

            
//  4. 关系流和Socket
            os.close();
            is.close();
            s.close(); 

上面这些只是一个单线程的服务端->客户端的程序,只能进行一次通讯,多次通讯将被告知无法连接。

这时,我们就需要用到进程Thread进行编程,将其改造成多线程聊天程序,可以同时进行多客户端的连接与发送信息。

代码如下:

// Server.java 

import  java.awt. * ;
import  java.net. * ;
import  java.io. *

public   class  Server  extends  Thread  {
    ServerSocket skt; 

    Socket Client[]
=new Socket[10];;
    Socket Client1
=null

    
int i = 0

    TextArea in; 

    
int port,k=0,l=0

    
//BufferedReader theInputStream; 

    PrintStream theOutputStream; 

    
//String readin; 

    Face chat; 

    
public Server(int port, Face chat) {
        
try {
            
this.port = port;
            skt 
= new ServerSocket(port);
            
this.chat = chat;
        }
 catch (IOException e) {
            chat.ta.append(e.toString());
        }

    }
 

    
public void run() 

        chat.ta.append(
"等待连线......"); 

        
while (true{
            
//System.out.print(""+i+" ");
            try {
             

                Client[k] 
= skt.accept(); /* 接收客户连接 */

                
//当有客户端连接时就新建一个子线程
                

                
if (i < 2{
                    ServerThread server[] 
= new ServerThread[10];
                     server[k]
= new ServerThread(Client[k], this.chat, i);
                     l
=server.length;
                     server[k].start();
                    chat.ta.append(
"客户端" + Client[k].getInetAddress() + "已连线 ");
                    
/*theInputStream = new BufferedReader(new InputStreamReader(Client
                            .getInputStream()));
*/

                    
//for(int j=0;j<server.length;j++)
                    theOutputStream = new PrintStream(server[k].getClient().getOutputStream());
                    i 
= server[k].getI();
                    k
++;
                }
 else {
                    
//theOutputStream = new PrintStream(null);
                }
 

            }
 catch (SocketException e) {
                
//chat.ta.append("连线中断! "); 

                
//chat.clientBtn.setEnabled(true);
                
//chat.serverBtn.setEnabled(true);
                
//chat.tfaddress.setEnabled(true);
                
//chat.tfport.setEnabled(true);
                
//try { 

                    
//skt.close();
                    
//Client.close();
                
//} catch (IOException err) {
                
//    chat.ta.append(err.toString());
                
//}
            }
 catch (IOException e) {
                chat.ta.append(e.toString());
            }

        }
 

    }
 

    
public void dataout(String data) {
        
//for(int j=0;j<l;j++)
        theOutputStream.println(data);
    }

}
 

class  ServerThread  extends  Thread  {
    ServerSocket skt; 

    Socket client; 

    TextArea in; 

    
int port; 

    
int i; 

    BufferedReader theInputStream; 

    PrintStream theOutputStream; 

    String readin; 

    Face chat; 

//服务端子线程 

    
public ServerThread(Socket s, Face chat, int i) {
        
this.i = ++i;
        client
= s;
        
//this.port = port;
        
//skt = new ServerSocket(port);
        this.chat = chat; 

    }
 

    
public int getI() {
        
return this.i;
    }

    
public Socket getClient() {
        
return this.client;
    }

    
public void run() 

        
//chat.ta.append("等待连线......"); 

        
try {
            
//Client = skt.accept(); /* 接收客户连接 */ 

            
//chat.ta.append("客户端" + Client.getInetAddress() + "已连线 ");
            theInputStream = new BufferedReader(new InputStreamReader(client
                    .getInputStream()));
            theOutputStream 
= new PrintStream(Client.getOutputStream()); 

            
while (true{
                readin 
= theInputStream.readLine();
                chat.ta.append(readin 
+ " ");
            }
 

        }
 catch (SocketException e) {
            chat.ta.append(
"连线中断! "); 

            chat.clientBtn.setEnabled(
true);
            chat.serverBtn.setEnabled(
true);
            chat.tfaddress.setEnabled(
true);
            chat.tfport.setEnabled(
true);
            
try {
                i
--;
                skt.close();
                client.close();
            }
 catch (IOException err) {
                chat.ta.append(err.toString());
            }

        }
 catch (IOException e) {
            chat.ta.append(e.toString());
        }

    }
 

    
public void dataout(String data) {
        theOutputStream.println(data);
    }

}
 

// Client.java 

import  java.net. * ;
import  java.io. * ;
import  javax.swing.Timer;
class  Client  extends  Thread  {
    Socket skt;
    InetAddress host;
    
int port; 

    BufferedReader theInputStream;
    PrintStream theOutputStream;
    String readin; 

    Face chat; 

    
public Client(String ip, int p, Face chat) {
        
try {
            host 
= InetAddress.getByName(ip);
            port 
= p;
            
this.chat = chat;
        }
 catch (IOException e) {
            chat.ta.append(e.toString());
        }

    }
 

    
public void run() {
        
try {
            chat.ta.append(
"尝试连线......"); 

            skt 
= new Socket(host, port);
            chat.ta.append(
"连线成功 "); 

            theInputStream 
= new BufferedReader(new InputStreamReader(skt
                    .getInputStream())); 

            theOutputStream 
= new PrintStream(skt.getOutputStream());
            
//Timer myTimer = new Timer();
            while (true{
                readin 
= theInputStream.readLine();
                chat.ta.append(readin 
+ " ");
            }

        }
 catch (SocketException e) {
            chat.ta.append(
"连线中断! ");
            chat.clientBtn.setEnabled(
true);
            chat.serverBtn.setEnabled(
true);
            chat.tfaddress.setEnabled(
true);
            chat.tfport.setEnabled(
true);
            
try {
                skt.close();
            }
 catch (IOException err) {
                chat.ta.append(err.toString());
            }

        }
 catch (IOException e) {
            chat.ta.append(e.toString());
        }

    }
 

    
public void dataout(String data) {
        theOutputStream.println(data);
    }

}
 

// 软件界面,进行按键监听调用。

// face.java 

import  java.awt. * ;
import  java.awt.event. *

public   class  Face  extends  Frame  {
    
/**
     * 
     
*/

    
private static final long serialVersionUID = 1L;
    Button clientBtn, serverBtn;
    TextArea ta;
    TextField tfaddress, tfport, tftype;
    
int port;
    Client client;
    Server server;
    
boolean iamserver;
    
static Face frm; 

    
public Face() {
        clientBtn 
= new Button("客户端");
        serverBtn 
= new Button("服务器");
        ta 
= new TextArea(""1050, TextArea.SCROLLBARS_BOTH);
        tfaddress 
= new TextField("192.168.1.104"20);
        tfport 
= new TextField("2000");
        tftype 
= new TextField(50); 

        tftype.addKeyListener(
new TFListener());
        ta.setEditable(
false); 

        setLayout(
new FlowLayout());
        add(tfaddress);
        add(tfport);
        add(clientBtn);
        add(serverBtn);
        add(ta);
        add(tftype);
        setSize(
400300);
        setTitle(
"我的聊天室");
        
this.setVisible(true); 

        clientBtn.addActionListener(
new ActionListener() {
            
public void actionPerformed(ActionEvent e) 

                port 
= Integer.parseInt(tfport.getText()); 

                client 
= new Client(tfaddress.getText(), port, frm); 

                client.start(); 

                tfaddress.setEnabled(
false);
                tfport.setEnabled(
false);
                serverBtn.setEnabled(
false);
                clientBtn.setEnabled(
false);
            }

        }
); 

        serverBtn.addActionListener(
new ActionListener() {
            
public void actionPerformed(ActionEvent e) 

                port 
= Integer.parseInt(tfport.getText()); 

                server 
= new Server(port, frm); 

                server.start(); 

                iamserver 
= true;
                tfaddress.setText(
"成为服务器"); 

                tfaddress.setEnabled(
false);
                tfport.setEnabled(
false);
                serverBtn.setEnabled(
false);
                clientBtn.setEnabled(
false);
            }

        }
); 

        addWindowListener(
new WindowAdapter() {
            
public void windowClosing(WindowEvent e) {
                System.exit(
0);
            }

        }
); 

    }
 

    
public static void main(String args[]) {
        frm 
= new Face();
    }
 

    
private class TFListener implements KeyListener {
        
public void keyPressed(KeyEvent e) 

            
if (e.getKeyCode() == KeyEvent.VK_ENTER) 

                ta.append(
">" + tftype.getText() + " "); 

                
if (iamserver)
                    server.dataout(tftype.getText());
                
else
                    client.dataout(tftype.getText()); 

                tftype.setText(
"");
            }

        }
 

        
public void keyTyped(KeyEvent e) {
        }
 

        
public void keyReleased(KeyEvent e) {
        }

    }

}


转载请注明:本文作者:longlongago     博客地址:http://blog.csdn.net/longlongago2000

这个程序我限制了连接数,大家可以根据自己的需要进行修改。

欢迎和我交流:email liufeituo@163.com

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值