通信基础——实现服务器与客户端的交流

通信基础——实现服务器与客户端的交流

大家好~~~好久不见~~~感谢大家一直以来对我的博客的关注与支持,最近比较忙~~技术博客写得少少的~~对不起一直关注我的朋友们~~现在~~我要写新东西啦~

是不是很期待呢,好的~~下面我将对我在通信方面的成果做一个展示:

服务器端:

下面是做服务器端的一点心得体会:

一、制作服务器端的三大步骤:

1、    在指定端口上创建一个java.net.ServerSocket对象;

2、    当服务器创建成功后,就像的的手机开机后,进入待机状态一样,你也要让服务器进入等待状态,当然是其他客户机来连接它;

3、    Socket连结对象上调用方法得到输入输出流;

4、    如果你使用过输入/输出流对象,也许不用看这步了;但我还是要提醒下,现在就可以通

信了:从输入流中读取数据,向输出流中写入数据,读到的,即是客户机发来的;

二、避免阻塞现象产生的方法是使用线程,使用线程在每次创建一个连接的时候,不然如果服务器不接收到消息就不会进入下一步,一直阻塞在那里;如果使用界面,建立连接时也需要使用线程;

三、在读取客户端发来的文本信息时,readline()读取中文不会出现乱码,如果按本文中的方法一个字节一个字节地读写就会出现乱码,因为中文占两个字节,不过不推荐使用readline,因为它只能读取文本格式的。

 

package Connect;

 

publicclass Connect2 {

 

   /**

    *@paramargs

    */

   publicstaticvoid main(String[] args) throws Exception {

      // TODO Auto-generated method stub

        Serverjframe serverjframe = new Serverjframe();

        serverjframe.Serverjfr();

 

            

   }

  

  

}

 

package Connect;

 

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

import javax.swing.JButton;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

public class JButtonListener implements ActionListener {

 

   private JTextArea jTextArea;

   private String str;

   private JTextField jTextField;

   private JButton jButton;

   private JTextField jTextFieldmsg;

   public JButtonListener(JTextField jTextField,JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg){

   this.jTextField = jTextField;

   this.jTextArea = jTextArea;

   this.jButton = jButton;

   this.jTextFieldmsg = jTextFieldmsg;

}

   @Override

   public void actionPerformed(ActionEvent e) {

     

      // TODO Auto-generated method stub

      str = jTextField.getText();

      int Str = Integer.parseInt(str);

      System.out.println(str);

      JframeThread jfThread = new JframeThread(Str,jTextArea,jButton,jTextFieldmsg);

      jfThread.start();

   }

 

}

 

 

package Connect;

 

import javax.swing.JButton;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

publicclass JframeThread extends Thread{

 

   private JButton jButton;

   private JTextField jTextFieldmsg;

   private JTextArea jTextArea;

   privateintStr;

   public JframeThread(int Str,JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg) {

      // TODO Auto-generated constructor stub

   this.Str = Str;

   this.jTextArea = jTextArea;

   this.jTextFieldmsg = jTextFieldmsg;

   this.jButton = jButton;

   }

   publicvoid run(){

      Netconnect netconnect = new Netconnect(jTextArea,jButton,jTextFieldmsg);

      netconnect.setUpServer(Str);

     

   }

}

 

package Connect;

 

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

public class JbuttonmsgListener  implements ActionListener{

 

   private ServerThread serverThread;

   private JTextField jTextField;

   private JTextArea jTextArea;

   public JbuttonmsgListener(JTextField jTextField,JTextArea jTextArea,ServerThread serverThread){

      this.jTextField = jTextField;

      this.jTextArea = jTextArea;

      this.serverThread = serverThread;

   }

   @Override

   public void actionPerformed(ActionEvent e) {

      // TODO Auto-generated method stub

      try {

        String string ="服务器说:"+jTextField.getText()+"\r\n";

        serverThread.sendMsg2Me(string);

          jTextArea.append(jTextField.getText());

      } catch (Exception e1) {

        // TODO Auto-generated catch block

        e1.printStackTrace();

      }

     

   }

 

}

 

package Connect;

 

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Random;

 

import javax.swing.JButton;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

public class Netconnect {

   private JTextArea jTextArea;

   private JButton jButton;

   private JTextField jTextFieldmsg;

   public Netconnect(JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg){

      this.jTextArea = jTextArea;

      this.jButton = jButton;

      this.jTextFieldmsg = jTextFieldmsg;

   }

 

   public void setUpServer(int port) {

      try {

        ServerSocket server=new ServerSocket(port);

        System.out.println("服务器创建成功!"+port);

        while(true)

        {

              Socket client = server.accept();

              System.out.println("已经启动一个线程,去处理它呵呵");

              ClientAlreadyConnect pClient = new ClientAlreadyConnect();

              pClient = pClient.createOne();

               System.out.println("用户:"+pClient.getName()+"已经被创建;");

              ServerThread st = new ServerThread(client,jTextArea,jButton,jTextFieldmsg,pClient);

              st.start();

             

          }

        } catch (IOException e) {

        // TODO Auto-generated catch block

        e.printStackTrace();

      }

     

   }

    

  

 

}

 

package Connect;

 

import java.awt.BorderLayout;

import java.awt.Dimension;

 

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

public class Serverjframe extends javax.swing.JFrame {

 

   public void Serverjfr(){

        this.setSize(400, 400);

        this.setTitle("呵呵服务器");

        this.setDefaultCloseOperation(3);

        this.setLocationRelativeTo(null);

        this.setLayout(new BorderLayout());

        //北部创建服务器

        JButton jButton = new JButton("端口号:");

        JTextField jTextField = new JTextField("8090");

        jTextField.setPreferredSize(new Dimension(100,30));

        JPanel northjPanel = new JPanel();

        northjPanel.add(jButton);

        northjPanel.add(jTextField);

        this.add(northjPanel,BorderLayout.NORTH);

        //中部输入框:

        JPanel jPanel = new JPanel();//面板

        JButton jButtonmsg = new JButton("发布消息");

        JTextField jTextFieldcenter = new JTextField();

        jTextFieldcenter.setPreferredSize(new Dimension(280,30));

        jTextFieldcenter.setHorizontalAlignment(JTextField.LEFT);

        jPanel.add(jButtonmsg);

        jPanel.add(jTextFieldcenter);

        this.add(jPanel,BorderLayout.CENTER);

        //南部显示框

        JPanel southjPanel = new JPanel();

        JTextArea jTextAreasouth = new JTextArea("");

        jTextAreasouth.setPreferredSize(new Dimension(350,260));

        southjPanel.add(jTextAreasouth);

        this.add(southjPanel,BorderLayout.SOUTH);

        this.setVisible(true);

        JButtonListener jButtonListener = new JButtonListener(jTextField,jTextAreasouth,jButtonmsg,jTextFieldcenter);

        jButton.addActionListener(jButtonListener);

   }

}

 

 

package Connect;

 

import java.io.DataInputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Random;

 

import javax.swing.JButton;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

public class ServerThread extends Thread{

 

   private Socket client;//线程对象要处理的连结变量

    private OutputStream out;

    private JTextArea jTextArea;

    private JButton jButton;

    private JTextField jTextFieldmsg;

    private ClientAlreadyConnect pClient;

    public ServerThread(JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg,ClientAlreadyConnect pClient){

      this.jTextArea =jTextArea;

      this.jButton = jButton;

      this.jTextFieldmsg = jTextFieldmsg;

      this.pClient = pClient;

    }

    public ServerThread(Socket sc,JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg,ClientAlreadyConnect pClient){

      this.client = sc;

      this.jTextArea = jTextArea;

      this.jButton = jButton;

      this.jTextFieldmsg = jTextFieldmsg;

      this.pClient = pClient;

    }

    public void sendMsg2Me(String msg) throws Exception{

      byte[] data = msg.getBytes();

      out.write(data);

      out.flush();

     

    }

    public void run(){

      //在线程run中调用处理节点的方法

      process(this.client);

    }

    private void process(Socket client) {

      try{

      JbuttonmsgListener jbmsgListener  = new JbuttonmsgListener(jTextFieldmsg,jTextArea,this);

      jButton.addActionListener(jbmsgListener);

      InputStream ins = client.getInputStream();

      out = client.getOutputStream();

      String string = " Hello,欢迎来的香煎马鲛鱼的服务器\r\n";

       this.sendMsg2Me(string);

       //调用读取字符串的方法,从输入流读取一个字符串

       String insputS = readString(ins);

       while(!insputS.equals("bye")){

         string = "(客户端"+pClient.getName()+"消息)";

         this.sendMsg2Me(string);

         jTextArea.append(string);

         insputS = readString(ins);

         String string2 = null;

         //System.out.println(string2);

         //this.sendMsg2Me(insputS);

 

       }

       string = "大爷走好~~以后常来玩啊~~\r\n";

       this.sendMsg2Me(string);

       client.close();

       insputS = readString(ins);

       }

      catch(Exception e){

       

      }

   }

    private String readString(InputStream ins) throws Exception{

      StringBuffer stb = new StringBuffer();

      int i = ins.read();

      char c = 0;

      while(c!=13){

      c = (char)i;

      stb.append(c);

      i = ins.read();

      }

      //将读到的字节组转为字符串,并调用trim去掉尾部的空格

      String inputS =stb.toString().trim(); 

      jTextArea.append(inputS);

      return inputS;

      }

   

     

}

//将发送信息的代码包装在一个方法中

 

package Connect;

import java.util.List;

import java.util.ArrayList;

 

public class Configstatic {

 

   public static List<ClientAlreadyConnect> allClient = new ArrayList<ClientAlreadyConnect>();

}

 

package Connect;

 

import java.io.DataInputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Random;

 

import javax.swing.JButton;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

public class ServerThread extends Thread{

 

   private Socket client;//线程对象要处理的连结变量

    private OutputStream out;

    private JTextArea jTextArea;

    private JButton jButton;

    private JTextField jTextFieldmsg;

    private ClientAlreadyConnect pClient;

    public ServerThread(JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg,ClientAlreadyConnect pClient){

      this.jTextArea =jTextArea;

      this.jButton = jButton;

      this.jTextFieldmsg = jTextFieldmsg;

      this.pClient = pClient;

    }

    public ServerThread(Socket sc,JTextArea jTextArea,JButton jButton,JTextField jTextFieldmsg,ClientAlreadyConnect pClient){

      this.client = sc;

      this.jTextArea = jTextArea;

      this.jButton = jButton;

      this.jTextFieldmsg = jTextFieldmsg;

      this.pClient = pClient;

    }

    public void sendMsg2Me(String msg) throws Exception{

      byte[] data = msg.getBytes();

      out.write(data);

      out.flush();

     

    }

    public void run(){

      //在线程run中调用处理节点的方法

      process(this.client);

    }

    private void process(Socket client) {

      try{

      JbuttonmsgListener jbmsgListener  = new JbuttonmsgListener(jTextFieldmsg,jTextArea,this);

      jButton.addActionListener(jbmsgListener);

      InputStream ins = client.getInputStream();

      out = client.getOutputStream();

      String string = " Hello,欢迎来的香煎马鲛鱼的服务器\r\n";

       this.sendMsg2Me(string);

       //调用读取字符串的方法,从输入流读取一个字符串

       String insputS = readString(ins);

       while(!insputS.equals("bye")){

         string = "(客户端"+pClient.getName()+"消息)";

         this.sendMsg2Me(string);

         jTextArea.append(string);

         insputS = readString(ins);

         String string2 = null;

         //System.out.println(string2);

         //this.sendMsg2Me(insputS);

 

       }

       string = "大爷走好~~以后常来玩啊~~\r\n";

       this.sendMsg2Me(string);

       client.close();

       insputS = readString(ins);

       }

      catch(Exception e){

       

      }

   }

    private String readString(InputStream ins) throws Exception{

      StringBuffer stb = new StringBuffer();

      int i = ins.read();

      char c = 0;

      while(c!=13){

      c = (char)i;

      stb.append(c);

      i = ins.read();

      }

      //将读到的字节组转为字符串,并调用trim去掉尾部的空格

      String inputS =stb.toString().trim(); 

      jTextArea.append(inputS);

      return inputS;

      }

   

     

}

//将发送信息的代码包装在一个方法中

 

客户端:

客户端需要的过程:

Socket client=new Socket(服务器IP,服务器端口);

只要如上代码执行成功,就算一个客户端连结上了服务器,接下来的流程和服务器端得到

Socket对象后的处理方式相同---Socket对象上得到输入输出流;

注意:如果断开服务器时报错,那么这个错误是正常出现的,不是程序问题;

测试过程中,先关客户端,再关服务器,不然会报很多错误,也许还会导致编译器无法正常运行,一定注意~~~

package Client;

 

import java.awt.BorderLayout;

import java.awt.Dimension;

 

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

 

public class Clientserver extends JFrame{

   

   public void Clientjfr(){

      this.setSize(500,400);

      this.setTitle("呵呵客户端");

      this.setDefaultCloseOperation(3);

      this.setLocationRelativeTo(null);

       //北部连接服务器

       JLabel jLabelIp =  new JLabel("Ip地址:");

        JLabel jLabel = new JLabel("端口号:");

        JButton jButton = new JButton("连接服务器");

        JTextField jTextFieldIp = new JTextField("localhost");

        JTextField jTextField = new JTextField("8090");

        jTextFieldIp.setPreferredSize(new Dimension(100,30));

        jTextField.setPreferredSize(new Dimension(100,30));

        JPanel northjPanel = new JPanel();

        //northjPanel.setSize(new Dimension(400,400));

        northjPanel.add(jLabelIp);

        northjPanel.add(jTextFieldIp);

        northjPanel.add(jLabel);

        northjPanel.add(jTextField);

        northjPanel.add(jButton);

       

        this.add(northjPanel,BorderLayout.NORTH);

        //中部文本输入框:

        JPanel jPanel = new JPanel();

        JButton jButtoncenter = new JButton("发布消息");

        JTextField jTextFieldcenter = new JTextField();

        jTextFieldcenter.setPreferredSize(new Dimension(360,30));

        jTextFieldcenter.setHorizontalAlignment(JTextField.LEFT);

        jPanel.add(jButtoncenter);

        jPanel.add(jTextFieldcenter);

        this.add(jPanel,BorderLayout.CENTER);

        //南部显示框

        String abcString = "收到的信息在此处显示";

        JPanel southjPanel = new JPanel();

        JTextArea jTextAreasouth = new JTextArea();

        jTextAreasouth.setPreferredSize(new Dimension(410,270));

        jTextAreasouth.append(abcString);

        southjPanel.add(jTextAreasouth);

        this.add(southjPanel,BorderLayout.SOUTH);

        this.setVisible(true);

        JButtonListener jbListener = new JButtonListener(jTextField,jTextFieldIp,jTextFieldcenter,jTextAreasouth,jButtoncenter);

        jButton.addActionListener(jbListener);

 

       

       

    }

}

  

package Client;

 

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.net.Socket;

 

import javax.swing.JTextArea;

 

public class Clientsotfware extends Thread {

   private JTextArea jTextAreasouth;

   private String ConnectIp;

   private int port;

   private OutputStream ouStream;// 到服务器的输出流

   private InputStream ins;// 到服务器的输入流

 

   public Clientsotfware(String ConnectIp, int port,JTextArea jTextAreasouth) {

      this.ConnectIp = ConnectIp;

      this.port = port;

      this.jTextAreasouth = jTextAreasouth;

   }

 

   public boolean ConnectTerminal() {

      try {

        // 创建一个服务器端的Socket对象

        Socket client = new Socket(ConnectIp, port);

        ins = client.getInputStream();

        // bfReader = new BufferedReader(new InputStreamReader(inStream));

        ouStream = client.getOutputStream();

        return true;

      } catch (Exception e) {

 

      }

      return false;

 

   }

 

   public void run() {

      while (true) {

        readFromServer();

      }

   }

 

   public void readFromServer() {

      try {

        String input = readString(ins);

         System.out.println(input);

         jTextAreasouth.append(input);

      } catch (Exception e) {

        e.printStackTrace();

      }

   }

 

   public void senMsg(String msg) {

      try {

       

        msg += "\r\n";

        this.ouStream.write(msg.getBytes());

        //System.out.println("客户端要发送的消息:"+msg);

        this.ouStream.flush();

        jTextAreasouth.append("客户端要发送的消息"+msg);

      } catch (Exception e) {

        e.printStackTrace();

      }

   }

 

   public String readString(InputStream ins) throws Exception {

      StringBuffer stb = new StringBuffer();

      int i = ins.read();

      char c = 0;

      while (c != 13) {

        stb.append(c);

        i = ins.read();

        c = (char) i;

       

      }

      String inputs = stb.toString().trim();

 

      return inputs;

   }

}

 

package Client;

 

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

import javax.swing.JButton;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

public class JButtonListener implements ActionListener{

   private JTextArea jTextAreasouth=null;

   private JTextField jTextField=null;

   private JTextField jTextFieldIp=null;

   private JTextField jTextFieldmsg = null;

   private JButton jButton=null;

   public  JButtonListener (JTextField jTextField,JTextField jTextFieldIp,JTextField jTextFieldmsg,JTextArea jTextAreasouth,JButton jButton){

      this.jTextField = jTextField;

      this.jTextFieldIp = jTextFieldIp;

      this.jTextAreasouth = jTextAreasouth;

      this.jTextFieldmsg = jTextFieldmsg;

      this.jButton = jButton;

   }

   @Override

   public void actionPerformed(ActionEvent e) {

      // TODO Auto-generated method stub

      int number=0;

      String stnumber ="";

      String str="0";

      stnumber = jTextField.getText();

      number = Integer.parseInt(stnumber);

      str = jTextFieldIp.getText();

      JframeThread jfThread = new JframeThread(number,str,jTextFieldmsg,jTextAreasouth,jButton);

      jfThread.start();

     

   }

 

}

 

 

package Client;

 

import java.util.Scanner;

 

import javax.swing.JButton;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

public class JframeThread extends Thread{

   private JTextArea jTextAreasouth;

   private JTextField jTextFieldmsg;

   private JButton jButton;

   private int number;

   private String str;

   public JframeThread(int number,String str,JTextField jTextFieldmsg,JTextArea jTextAreasouth,JButton jButton){

      this.number = number;

      this.str = str;

      this.jTextFieldmsg = jTextFieldmsg;

      this.jTextAreasouth =jTextAreasouth;

      this.jButton = jButton;

   }

   public void run(){

      String msg=null;

      Clientsotfware clientsotfware = new Clientsotfware(str,number,jTextAreasouth);

        if(clientsotfware.ConnectTerminal()){

        clientsotfware.start();

         System.out.println("输入要发送的消息:");

        SenMsgListener senListener = new SenMsgListener(clientsotfware,jTextFieldmsg);

        jButton.addActionListener(senListener);        }

 

}

   }

 

package Client;

 

import java.util.Scanner;

 

 

 

publicclass netClient {

 

   /**

    *@paramargs

    */

   publicstaticvoid main(String[] args) {

     // TODO Auto-generated method stub

        Clientserver clserver = new Clientserver();

        clserver.Clientjfr();

  

 

}

}

 

 

package Client;

 

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

import javax.swing.JTextField;

 

public class SenMsgListener implements ActionListener{

   private Clientsotfware clientsotfware;

   private JTextField jTextFieldmsg;

    public SenMsgListener(Clientsotfware clientsotfware,JTextField jTextFieldmsg) {

   // TODO Auto-generated constructor stub

      this.clientsotfware = clientsotfware;

      this.jTextFieldmsg = jTextFieldmsg;

     

}

   @Override

   public void actionPerformed(ActionEvent e) {

      // TODO Auto-generated method stub

      clientsotfware.senMsg(jTextFieldmsg.getText());

      jTextFieldmsg.setText("");

   }

 

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值