【Little_things】事件驱动的带界面的Client/Server聊天小程序(java socket)

 

 1.可以实时刷新,

 2.不用双方交替输入接受可以一个方发送多条的局域网内聊天小程序

 3.解决通信时中文乱码问题


Client代码


package com.try02;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 * Created by ztc on 15-11-1.
 */
public class Client2 extends JFrame implements ActionListener,KeyListener{
    
    JTextArea jta=null;
    JTextField jtf=null;
    JButton jb=null;
    JPanel jp1=null;
    JScrollPane jsp=null;
    Socket cl=null;
    public static void main(String[] args){
        Client2 c2=new Client2();
    }
    public Client2(){

        jta=new JTextArea();
        //  参数是宽度
        jtf=new JTextField(15);
        jb=new JButton("Send!");
        //添加动作监听
        jb.addActionListener(this);
        jp1=new JPanel();
        //参数为要加滚动条的组件,返回的为加完滚动条的组件
        jsp=new JScrollPane(jta);
        //添加键盘监听
        jtf.addKeyListener(this);
        jp1.add(jtf);
        jp1.add(jb);
        this.add(jsp,"Center");
        this.add(jp1,"South");

        this.setTitle("Client");
        this.setSize(300,300);
        this.setLocation(500,200);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        try{
            cl=new Socket("192.168.16.100",9999);
            InputStreamReader in=new InputStreamReader(cl.getInputStream(),"UTF-8");
            BufferedReader br=new BufferedReader(in);
            while(true)
            {
                String msg=br.readLine();
                jta.append(msg+"\r\n");
                if(msg.equals("bye"))
                {
                    cl.close();
                    break;
                }
            }
        }catch (IOException e){
            e.printStackTrace();
        }

    }

    public void actionPerformed(ActionEvent a){
        try {
            if (a.getSource() == jb) {
                PrintWriter pw = new PrintWriter(cl.getOutputStream(),true);
                pw.println("Client:\t" + jtf.getText());
                jta.append("Client:\t" + jtf.getText() + "\r\n");
                jtf.setText("");
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    public void keyTyped(KeyEvent k){
    }
    public void keyReleased(KeyEvent k){
    }
    //回车发送
    public void keyPressed(KeyEvent k){
        try {
            if (k.getKeyCode() == KeyEvent.VK_ENTER) {
                PrintWriter pw = new PrintWriter(cl.getOutputStream(),true);
                pw.println("Client:\t" + jtf.getText());
                jta.append("Client:\t" + jtf.getText() + "\r\n");
                jtf.setText("");
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}


Server代码

package com.try02;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by ztc on 15-11-1.
 */
public class Server2 extends JFrame implements ActionListener,KeyListener{
    JTextArea jta=null;
    JTextField jtf=null;
    JButton jb=null;
    JPanel jp1=null;
    JScrollPane jsp=null;
    Socket s=null;
    public static void main(String[] args){
        Server2 s2=new Server2();
    }

    public Server2(){

        jta=new JTextArea();
        //  参数是宽度
        jtf=new JTextField(15);    
        jb=new JButton("Send!");
        //给按钮添加动作监听
        jb.addActionListener(this);
        jp1=new JPanel();
        //参数为要加滚动条的组件,返回的为加完滚动条的组件
        jsp=new JScrollPane(jta);
        //给输入框加键盘监听
        jtf.addKeyListener(this);
        jp1.add(jtf);
        jp1.add(jb);
        this.add(jsp,"Center");
        this.add(jp1,"South");

        this.setTitle("Server");
        this.setSize(300,300);
        this.setLocation(500,200);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        try{
            //启动服务器监听 9999 端口
            ServerSocket ser=new ServerSocket(9999);
            s=ser.accept();
            //获得实时刷新的输入流
            InputStreamReader in=new InputStreamReader(s.getInputStream(),"UTF-8");
            BufferedReader br=new BufferedReader(in);
            //不断读取
            while(true)
            {
                String msg=br.readLine();
                jta.append(msg+"\r\n");
                if(msg.equals("bye"))
                {
                    ser.close();
                    break;
                }
            }

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

    }

    public void actionPerformed(ActionEvent arg0){
        try{
            if(arg0.getSource()==jb) {
                PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
                pw.println("Server:\t" + jtf.getText());
                jta.append("Server:\t" + jtf.getText()+"\r\n");
                jtf.setText("");
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    public void keyTyped(KeyEvent k){
    }
    public void keyReleased(KeyEvent k){
    }
    //按下回车发送
    public void keyPressed(KeyEvent k){     
        try {
            if (k.getKeyCode() == KeyEvent.VK_ENTER) {
                PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
                pw.println("Server:\t" + jtf.getText());
                jta.append("Server:\t" + jtf.getText() + "\r\n");
                jtf.setText("");
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }



}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码是一个简单的基于传输层的协议的模拟程序,其中包含了发送方和接收方的函数实现。 其中,发送方的函数名为sender2(),其主要功能是从网络层获取数据,将数据封装成帧并通过物理层发送出去,然后等待接收到“帧到达”事件后再继续执行。具体实现步骤如下: 1. 从网络层获取数据,保存到packet类型的buffer变量中。 2. 将buffer变量中的数据封装成帧,保存到frame类型的s变量中。 3. 调用to_physical_layer()函数,将s变量中的帧通过物理层发送出去。 4. 调用wait_for_event()函数,等待接收到“帧到达”事件后再继续执行。 接收方的函数名为receiver2(),其主要功能是接收帧,将帧中的数据传递给网络层,然后发送一个dummy帧给发送方,以唤醒发送方并继续发送数据。具体实现步骤如下: 1. 调用wait_for_event()函数,等待接收到“帧到达”事件后再继续执行。 2. 调用from_physical_layer()函数,从物理层接收到帧,并保存到frame类型的r变量中。 3. 将r变量中的帧中的数据传递给网络层,通过调用to_network_layer()函数实现。 4. 构造一个dummy帧,保存到frame类型的s变量中。 5. 调用to_physical_layer()函数,将dummy帧通过物理层发送出去,以唤醒发送方并继续发送数据。 需要注意的是,这段代码中只实现了基本的功能,并没有考虑实际环境中可能出现的错误和异常情况,例如帧的丢失、损坏、重传等。如果要实现一个真正可靠的协议,需要考虑更多的细节和情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值