以前用linux c实现过简单的聊天程序,但毕竟用linux的人不多,只能自己ping自己。最近用java实现了,其中主要用到了java的网络编程,GUI编程,IO编程。整个程序总共有三个线程,线程1为界面程序+客户端,线程2为服务器,线程3为接收发来消息的方法。程序启动后,线程1启动,随之线程2启动,当建立连接后,线程3启动。当然这只是最初的版本,有待改进。以后最重要的改进还是对于多人聊天的并发处理。此程序用法很简单,内网和外网都适用,(端口号我设定的是1080,一些用路由器的朋友要把自己的内网ip映射到外网ip,具体做法参考下方有图示), 不多废话啦,看程序吧。。。
先看两张截图:
路由器分配的为内网IP(192.168.1.XXX),如果想被外网IP访问,必须要把你的内网IP映射到外网IP。(如果想访问别人,则无需设置)首先登陆你的路由器设置页面(浏览器中输入192.168.1.1),然后选择转发规则进行设置:端口号设置为1080,IP设置为本机的内网IP。
一下为程序源代码,注释有点少,有疑问或者更好建议的朋友请给我留言。
- import javax.swing.*;
- import java.awt.event.*;
- import javax.swing.border.Border;
- import javax.swing.border.LineBorder;
- import javax.swing.text.BadLocationException;
- import java.io.*;
- import java.net.*;
- import java.awt.event.*;
- import java.awt.*;
- import java.util.*;
- import java.text.*;
- public class SeekYou {
- public static void main(String[] args){
- Recv r = new Recv();
- new Thread(r).start();
- }
- }
- class Recv implements Runnable{
- InterFace inf = new InterFace();
- public void run(){
- try {
- ServerSocket ss = new ServerSocket(1080);
- Socket s = ss.accept();
- inf.connectInformation(s);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- class InterFace implements Runnable{
- // 网络连接的套接字
- Socket sock = null;
- InputStream is = null;
- OutputStream os = null;
- // 聊天界面的顶层容器
- JFrame jf = new JFrame("Seek You");
- // 聊天界面的顶部
- JPanel p = new JPanel();
- JLabel l = new JLabel("Input His/Her IP: ");
- final JTextField tf = new JTextField(20);
- JButton bt = new JButton("Connect");
- // 聊天界面的中部
- JScrollPane js = new JScrollPane();
- TextArea ta = new TextArea();
- // 聊天界面的底部
- JPanel p2 = new JPanel();
- JTextField tff = new JTextField(40);
- JButton btt = new JButton("Send");
- InterFace()
- {
- // 聊天界面的顶层容器
- jf.setSize(600,400);
- jf.setLocation(340,160);
- jf.setVisible(true);
- // 聊天界面的顶部
- tf.addKeyListener(new KeyAdapter(){
- public void keyPressed(KeyEvent e) {
- if( e.getKeyChar() == KeyEvent.VK_ENTER){
- bt.doClick();
- }
- }
- });
- p.add(l);
- p.add(tf);
- p.add(bt);
- jf.getContentPane().add(p,BorderLayout.NORTH);
- // 添加indowListener
- jf.addWindowListener(new WindowAdapter(){
- public void windowClosing(WindowEvent e){
- try {
- if(is != null)
- is.close();
- if(os != null)
- os.close();
- if(sock != null)
- sock.close();
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- System.exit(0);
- }
- });
- // 聊天界面的中部
- ta.setBackground(Color.gray);
- ta.setForeground(Color.white);
- // js.add(ta);
- jf.getContentPane().add(ta,BorderLayout.CENTER);
- // 聊天界面的底部
- tff.addKeyListener(new KeyAdapter(){
- public void keyPressed(KeyEvent e) {
- if( e.getKeyChar() == KeyEvent.VK_ENTER){
- btt.doClick();
- }
- }
- });
- p2.add(tff);
- p2.add(btt);
- jf.getContentPane().add(p2,BorderLayout.SOUTH);
- // 实现Send的侦听
- btt.addActionListener(new ActionListener(){
- public void actionPerformed(ActionEvent e){
- if(sock == null){
- String line = System.getProperty("line.separator");
- tff.setText("");
- ta.append("您还没有建立连接");
- ta.append(line);
- }
- else{
- String s = tff.getText();
- tff.setText("");
- try {
- String line = System.getProperty("line.separator");
- os.write(s.getBytes());
- ta.append("Me: "+s);
- ta.append(line);
- } catch (Exception e1) {
- e1.printStackTrace();
- }
- }
- }
- });
- // 实现connect的监听
- bt.addActionListener(new ActionListener(){
- public void actionPerformed(ActionEvent e){
- if(sock ==null){
- try {
- sock = new Socket(tf.getText(),1080);
- is = sock.getInputStream();
- os = sock.getOutputStream();
- String line = System.getProperty("line.separator");
- ta.append("您已经和"+sock.getInetAddress().getHostName()+"建立连接");
- ta.append(line);
- recvst();//启动接收信息的进程
- }
- catch (Exception e1) {
- String line = System.getProperty("line.separator");
- ta.append("连接失败,请重新输入IP进行连接");
- ta.append(line);
- e1.printStackTrace();
- }
- }else{
- String line = System.getProperty("line.separator");
- ta.append("您已经和"+sock.getInetAddress().getHostName()+"建立连接,");
- ta.append("重新启动可以建立其他连接");
- ta.append(line);
- }
- }
- });
- }
- final void recvst(){
- new Thread(this).start();
- }
- void connectInformation(Socket s){
- if(sock==null){
- sock = s;
- String line = System.getProperty("line.separator");
- ta.append(s.getInetAddress().getHostName()+"已经连接到你的电脑");
- ta.append(line);
- ta.append(Calendar.getInstance().getTime()+"");
- ta.append(line);
- try {
- is = s.getInputStream();
- os = s.getOutputStream();
- recvst();//启动接收信息的进程
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- else{
- String line = System.getProperty("line.separator");
- ta.append(s.getInetAddress().getHostName()+"正在连接到你的电脑...");
- ta.append("但您已经和"+sock.getInetAddress().getHostName()+"建立连接");
- ta.append(line);
- ta.append(Calendar.getInstance().getTime()+"");
- ta.append(line);
- }
- }
- /*
- void wordclear(){
- String input = ta.getText();
- String[] regStr = input.split( "line.separator") ;
- int i = 0;
- for(String s : regStr){i++;}
- if(i==14){
- ta.setText("");
- }
- }
- */
- public void run(){
- // new Thread(new WordClear(ta)).start();//开启文本域字数控制线程
- while(true){
- if(is!=null){
- String line = System.getProperty("line.separator");
- byte[] buf = new byte[100];
- try {
- int len = is.read(buf);
- if(len != 0){
- ta.append("You: "+new String(buf, 0, len));
- ta.append(line);
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- }
- /*
- class WordClear implements Runnable{
- TextArea ta;
- WordClear(TextArea ta){
- this.ta = ta;
- }
- String ss;
- public void run(){
- while(true){
- System.out.println("!!!!!!!!!");
- String input = ta.getText();
- String[] regStr = input.split( "/n") ;
- int i = 0;
- for(String s : regStr){
- i++;
- if(i>16){
- ss = s+"/n";
- }
- }
- if(i==17){
- try {
- ta.setText(ss);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
- */