黑马程序员---Socket和GUI的应用

---------------------- android培训java培训、期待与您交流!


Socket编程感觉和IO流联系紧密
尤其是TCP连接
Server端和Client端直接用流来传输数据

Socket感觉很重要
点对点聊天 上传文件 客户端与服务器的交互
小应用写了很多 
学习Socket的过程中
感觉IO流已经搞得滚瓜乱熟了
这倒是意外收获...

最后加上GUI一起 
写了一个在线的聊天室
算是这3个的综合应用了


import java.net.*;
import java.io.*;
import java.util.*;

public class ChatRoomServer {
	public static final int PORT=11314;
	private static final int MAXSOCKET=10;			//最大连接数
	private ServerSocket ss=null;
	private Vector<Socket> allSocket=null;			//存放所有连接上的Socket,由于多线程操作,就用Vector了

	public ChatRoomServer(){
		try{
			ss=new ServerSocket(PORT);
			allSocket=new Vector<Socket>();
			Socket s=null;
			while((s=ss.accept())!=null){
				if(allSocket.size()<MAXSOCKET)
					new ClientThread(s);
				else
					s.close();
			}
		}catch(Exception e){
			throw new RuntimeException("服务端创建失败");
		}
	}
	class ClientThread implements Runnable{			//新线程
		private Socket socket=null;
		private Thread thread=null;
		private InputStream is=null;
		private OutputStream os=null;
		private BufferedReader br=null;
		private BufferedWriter bw=null;
		private String name=null;					//昵称
		public ClientThread(Socket socket){
			this.socket=socket;
			try{
				is=socket.getInputStream();
				os=socket.getOutputStream();
				br=new BufferedReader(new InputStreamReader(is));
				bw=new BufferedWriter(new OutputStreamWriter(os));
				name=br.readLine();
			}catch(Exception e){
					try{
						if(socket!=null){
							System.out.println(socket.getInetAddress().getHostAddress()+" 创建数据流失败,连接断开");
							socket.close();
						}
					}catch(Exception ex){
						ex.printStackTrace();
					}finally{
						return;
					}
			}
			System.out.println(socket.getInetAddress().getHostAddress()+" 进入了聊天室");
			showChat(name+" 进入了聊天室");
			allSocket.add(socket);
			thread=new Thread(this);
			thread.start();
		}
		@Override
		public void run() {
			byte[] buf = new byte[1024*64];
			int len = 0;
			try{
				while ((len = is.read(buf)) != -1) {
					showChat(name+":"+new String(buf,0,len));
				}
			}catch(Exception e){
				System.out.println(socket.getInetAddress().getHostAddress()+" 中断连接");
			}
			try{
				if(socket!=null){
					System.out.println(socket.getInetAddress().getHostAddress()+" 离开了聊天室");
					showChat(name+" 离开了聊天室");
					allSocket.remove(socket);				//离开时要把Socket从Vector中去掉
					socket.close();
				}
			}catch(Exception ex){
				ex.printStackTrace();
			}finally{
				thread.stop();
			}
		}
	}
	public void showChat(String str){				//客户端发来聊天信息时,调用这个函数,遍历所有Socket再把消息转发出去
		for(Socket s:allSocket){
			try{
				OutputStream os=s.getOutputStream();
				os.write(str.getBytes());
				os.write(13);
				os.write(10);
				os.flush();
			}catch(Exception e){
				continue;
			}
		}
	}
	public static void main(String[] args){
		new ChatRoomServer();
	}
}

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

import javax.swing.*;

public class ChatRoomClient{
	private JFrame fmMain=null;
	private JLabel[] jlOption=new JLabel[3];
	private JTextField[] jtfOption=new JTextField[3];
	private JButton jbLogin=null;
	private JTextArea jtaChat=null;
	private JTextField jtfInput=null;
	private Container c=null;
	
	private BufferedReader br=null;
	private BufferedWriter bw=null;
	private Socket socket=null;
	private BufferedReader sbr=null;
	private BufferedWriter sbw=null;
	private Thread receiveThread=null;
	
	public ChatRoomClient(){
		fmMain=new JFrame("聊天室");
		jlOption[0]=new JLabel("昵称");
		jlOption[1]=new JLabel("主机地址");
		jlOption[2]=new JLabel("端口号");
		for(int i=0;i<3;i++)
			jtfOption[i]=new JTextField(10);
		jbLogin=new JButton("连接");
		jtaChat=new JTextArea(50,20);
		jtfInput=new JTextField(20);
		c=fmMain.getContentPane();
		
		fmMain.setBackground(Color.white);
		fmMain.setSize(600,400);
		fmMain.setLocation(150,100);
		fmMain.setLayout(null);
		fmMain.setVisible(true);
		fmMain.setResizable(false);
		fmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		jtaChat.setBounds(10,10,572,280);
		jtfInput.setBounds(10,316,572,30);
		jtaChat.setEditable(false);
		
		for(int i=0;i<3;i++){
			fmMain.add(jlOption[i]);
			fmMain.add(jtfOption[i]);
			jlOption[i].setBounds(200,60+60*i,60,20);
			jtfOption[i].setBounds(300,60+60*i,100,20);
			
		}
		fmMain.add(jbLogin);
		jbLogin.setBounds(260,260,60,20);
		jbLogin.addActionListener(new ActionListener(){				//按钮点击事件
			public void actionPerformed(ActionEvent e){
				connect(jtfOption[0].getText(),jtfOption[1].getText(),jtfOption[2].getText());
			}
		});
		jtfInput.addKeyListener(new KeyAdapter(){					//聊天框回车事件
			public void keyPressed(KeyEvent e){
				if(e.getKeyCode()==KeyEvent.VK_ENTER){
					try{
						sbw.write(jtfInput.getText());
						sbw.flush();
						jtfInput.setText("");
					}catch(Exception ex){
						ex.printStackTrace();
					}
					
				}
			}
		});
	}
	
	public void showLogin(){
		for(int i=0;i<3;i++){
			fmMain.add(jlOption[i]);
			fmMain.add(jtfOption[i]);
		}
		fmMain.add(jbLogin);
		fmMain.remove(jtaChat);
		fmMain.remove(jtfInput);
		fmMain.repaint();
	}
	public void hideLogin(){
		for(int i=0;i<3;i++){
			fmMain.remove(jlOption[i]);
			fmMain.remove(jtfOption[i]);
		}
		fmMain.remove(jbLogin);
		fmMain.add(jtaChat);
		fmMain.add(jtfInput);
		fmMain.repaint();
	}
	
	public void connect(String name,String address,String port){		//登陆函数
		try{
			socket=new Socket(address,Integer.parseInt(port));
			sbr=new BufferedReader(new InputStreamReader(socket.getInputStream()));
			sbw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		}catch(Exception e){
			JOptionPane.showMessageDialog(fmMain,"连接失败");			//不判断主机名和端口号的填写正确性了,直接连接然后抓异常
			return;
		}
		hideLogin();
		br=new BufferedReader(new InputStreamReader(System.in));
		bw=new BufferedWriter(new OutputStreamWriter(System.out));
		try{
			sbw.write(name);
			sbw.newLine();
			sbw.flush();
		}catch(IOException e){
			e.printStackTrace();
		}
		receiveThread=new Thread(new Receive());
		receiveThread.start();
	}
	
	class Receive implements Runnable{
		@Override
		public void run(){
			String str=null;
			try{
				while((str=sbr.readLine())!=null){
					jtaChat.append(str);
					jtaChat.append("\r\n");
					if(jtaChat.getLineCount()>=17){
						String s=jtaChat.getText();
						jtaChat.setText(s.substring(s.indexOf("\r\n")+2));
					}
				}
			}catch(Exception e){
				JOptionPane.showMessageDialog(fmMain,"连接中断");		//主机的连接数达到最大时,客户端会执行到这里
				try{
					socket.close();
				}catch(Exception ex){
					ex.printStackTrace();
				}
				showLogin();
			}
		}
	}

	public static void main(String[] args){
		new ChatRoomClient();
	}
}



 -------------------------------------------- android培训java培训、期待与您交流! ----------------------

详细请查看: http://edu.csdn.net/heima
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值