利用TCP实现简单聊天程序
2017-04-23 22:16
836 查看
TCP通信的特点是面向连接,即通信双方必须先建立连接然后才能进行通信,安全性比较高,保证信息的正确性。
服务器端:
客户端:
先打开服务器端,此时服务器端监听9999号端口;然后打开客户端,这时候服务器端将输出客户端的IP地址。
发送字符串数据:
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os);
ps.println("content");
接收字符串数据:
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str = br.readLine();
readLine函数也是一个死等函数,如果客户端连接上了,但是没有发送信息,就会造成阻塞。所以最好的解决方法是将读取信息的代码写在线程内。
知道了怎么发送、接收数据之后,服务器端先打开端口并监听,假如有客户端连接则开启线程,重写run()方法。相互通信时并不知道对方什么时候发送信息,所以就需要线程来实现自动接收信息的功能,然后需要一个发送信息的函数,在这里我选择button按钮的点击事件来实现,发送消息时直接在输入框回车就可以了。
服务器端:
客户端:
服务器端不知道客户端什么时候连接,所以就需要一个线程专门负责多个客户端连接;当客户端连接上之后,不知道什么时候会发送消息,所以需要单独为这个客户端开一个线程来不停的读取它发送过来的消息,在程序代码中用ArrayList动态数组来保存每个每一个客户端的线程;服务器端接收到某个客户端发送的消息,需要将消息转发给其他客户端,这就需要服务器端保存各个客户端的输入输出流的引用。
由于是多客户聊天,需要一个name来区别每个客户端。客户端没多大变化,同样在run()函数中编写接收消息的代码,用按钮点击事件来发送消息。
服务器端:
首先打开服务器端,然后打开客户端输入客户端name,分别是Dkangel、Lisi、Zhangsan,然后在各自的输入框内输入信息,回车即可发送消息。
以上就是我所要介绍的TCP实现简单聊天程序。
不久前还写了UDP实现简单聊天程序。
先介绍客户端怎么连接服务器端:
服务器打开某个端口并进行监听,等待客户端连接;客户端根据服务器的IP地址,连接服务器的某个端口。服务器端用ServerSocket(port)打开port端口并监听,客户端用Socket(IP,port)连接服务器端的port端口。在服务器端用accept函数来接受客服端的socket对象。accept函数是一个死等函数,如果没有客户端连接,程序将会在这里阻塞知道有客户端连接。服务器端:
package Easy; import java.net.ServerSocket; import java.net.Socket;
public class Server { private int Port = 9999; private ServerSocket SS; private Socket socket; public Server(){ try{ SS = new ServerSocket(Port); socket = SS.accept(); String ipAddress = socket.getInetAddress().getHostAddress();
System.out.println("客户端" + ipAddress + "连接"); }catch(Exception ex){ } } public static void main(String[] args){ new Server(); } }
客户端:
package Easy; import java.net.InetAddress d38b ; import java.net.Socket; public class Client { public static void main(String[] args) throws Exception{ InetAddress ip = InetAddress.getByName("Localhost"); int Port = 9999; Socket socket = new Socket(ip,Port); } }
先打开服务器端,此时服务器端监听9999号端口;然后打开客户端,这时候服务器端将输出客户端的IP地址。
如何实现客户端与服务器端的相互通信?(单)
要知道怎么实现相互通信,首先得知道怎么发送数据和接收数据。发送字符串数据:
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os);
ps.println("content");
接收字符串数据:
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str = br.readLine();
readLine函数也是一个死等函数,如果客户端连接上了,但是没有发送信息,就会造成阻塞。所以最好的解决方法是将读取信息的代码写在线程内。
知道了怎么发送、接收数据之后,服务器端先打开端口并监听,假如有客户端连接则开启线程,重写run()方法。相互通信时并不知道对方什么时候发送信息,所以就需要线程来实现自动接收信息的功能,然后需要一个发送信息的函数,在这里我选择button按钮的点击事件来实现,发送消息时直接在输入框回车就可以了。
服务器端:
package Alone; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; public class AServer extends JFrame implements ActionListener,Runnable { private int Port = 9999; private ServerSocket SS; private Socket socket; private JTextArea area = new JTextArea("聊天内容:"+'\n'); private JTextField field = new JTextField(""); public AServer(){ this.setTitle("服务器"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.add(area,BorderLayout.CENTER); this.add(field,BorderLayout.NORTH); field.addActionListener(this); this.setSize(190, 200); this.setVisible(true); try{ SS = new ServerSocket(Port); socket = SS.accept(); new Thread(this).start(); }catch(Exception ex){ } } public void run(){ try{ while(true){ InputStream is = socket.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String str = br.readLine(); area.append(str + '\n'); } }catch(Exception ex){ } } public void actionPerformed(ActionEvent e){ try{ OutputStream os = socket.getOutputStream(); PrintStream ps = new PrintStream(os); ps.println("服务器说:" + field.getText()); field.setText(""); }catch(Exception ex){ } } public static void main(String[] args){ new AServer(); } }
客户端:
package Alone; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.InetAddress; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; public class AClient extends JFrame implements ActionListener, Runnable { private Socket socket; private int Port = 9999; private InetAddress ip; private JTextArea area = new JTextArea("聊天内容:\n"); private JTextField field = new JTextField(""); public AClient(){ this.setTitle("客户端"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.add(field,BorderLayout.NORTH); field.addActionListener(this); this.add(area, BorderLayout.CENTER); this.setSize(190, 200); this.setVisible(true); try{ ip = InetAddress.getByName("Localhost"); socket = new Socket(ip,Port); OutputStream os = socket.getOutputStream(); PrintStream ps = new PrintStream(os); ps.println("客户端连接"); new Thread(this).start(); }catch (Exception ex){ } } public void run(){ try{ while(true){ InputStream is = socket.getInputStream(); BufferedReader bf = new BufferedReader(new InputStreamReader(is)); String str = bf.readLine(); area.append(str + '\n'); } }catch (Exception ex){ } } public void actionPerformed(ActionEvent e){ try{ OutputStream os = socket.getOutputStream(); PrintStream ps = new PrintStream(os); ps.println("客户端说:" + field.getText()); field.setText(""); }catch (Exception ex){ } } public static void main(String[] args) { new AClient(); } }实验过程:
多客户聊天(多)
在实际的应用中,聊天程序是客户端与客户端聊天,而不是客户端与服务器端聊天。要是现这个功能,服务器端就要起到一个转发的作用。服务器端不知道客户端什么时候连接,所以就需要一个线程专门负责多个客户端连接;当客户端连接上之后,不知道什么时候会发送消息,所以需要单独为这个客户端开一个线程来不停的读取它发送过来的消息,在程序代码中用ArrayList动态数组来保存每个每一个客户端的线程;服务器端接收到某个客户端发送的消息,需要将消息转发给其他客户端,这就需要服务器端保存各个客户端的输入输出流的引用。
由于是多客户聊天,需要一个name来区别每个客户端。客户端没多大变化,同样在run()函数中编写接收消息的代码,用按钮点击事件来发送消息。
服务器端:
package Group; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class GServer implements Runnable { private int Port = 9999; private ServerSocket SS; private Socket socket; private ArrayList clients = new ArrayList(); //保存客户端线程 public GServer(){ try{ SS = new ServerSocket(Port); new Thread(this).start(); }catch(Exception ex){ } } public void run(){ try{ while(true){ socket = SS.accept(); ChatThread ct = new ChatThread(socket); clients.add(ct); ct.start(); } }catch(Exception ex){ } } class ChatThread extends Thread{ private Socket s; private InputStream is; private OutputStream os; private BufferedReader br; private PrintStream ps; public ChatThread(Socket socket) throws Exception{ this.s = socket; is = this.s.getInputStream(); os = this.s.getOutputStream(); br = new BufferedReader(new InputStreamReader(is)); ps = new PrintStream(os); } public void run(){ try{ while(true){ String str = br.readLine(); sendMessage(str); } }catch (Exception ex){ } } public void sendMessage(String str){ for(int i=0; i<clients.size(); i++){ ChatThread ct = (ChatThread)clients.get(i); ct.ps.println(str); } } } public static void main(String[] args){ new GServer(); } }客户端:
package Group; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.InetAddress; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class GClient extends JFrame implements ActionListener, Runnable { private Socket socket; private int Port = 9999; private InetAddress ip; private String name; private JTextArea area = new JTextArea("以下是聊天内容:\n"); private JTextField field = new JTextField(""); public GClient(){ this.setTitle("客户端"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.add(field,BorderLayout.NORTH); field.addActionListener(this); this.add(area, BorderLayout.CENTER); this.setSize(240, 260); this.setVisible(true); name = JOptionPane.showInputDialog("输入昵称:"); try{ ip = InetAddress.getByName("Localhost"); socket = new Socket(ip,Port); JOptionPane.showMessageDialog(this, "连接成功"); this.setTitle("客户端:" + name); new Thread(this).start(); }catch (Exception ex){ } } public void run(){ try{ while(true){ InputStream is = socket.getInputStream(); BufferedReader bf = new BufferedReader(new InputStreamReader(is)); String str = bf.readLine(); area.append(str + '\n'); } }catch (Exception ex){ } } public void actionPerformed(ActionEvent e){ try{ OutputStream os = socket.getOutputStream(); PrintStream ps = new PrintStream(os); ps.println(name + "说:" + field.getText()); field.setText(""); }catch (Exception ex){ } } public static void main(String[] args) { new GClient(); } }实验过程:
首先打开服务器端,然后打开客户端输入客户端name,分别是Dkangel、Lisi、Zhangsan,然后在各自的输入框内输入信息,回车即可发送消息。
以上就是我所要介绍的TCP实现简单聊天程序。
不久前还写了UDP实现简单聊天程序。
相关文章推荐
- java用socket和serversocket实现一对一聊天(java实现简单的TCP聊天程序)
- java学习之利用TCP实现的简单聊天示例代码
- linux下TCP/IP实现简单聊天程序
- 利用TCP传输协议实现基于Socket的聊天程序
- java实现简单TCP聊天程序
- 利用TCP和UDP协议,实现基于Socket的小聊天程序(初级版)
- java用ServerSocket类结合io流实现一对一聊天(java实现简单的TCP聊天程序只能用telnet连接后方可使用)
- 利用TCP和UDP协议,实现基于Socket的小聊天程序
- linux下TCP/IP实现简单聊天程序
- Socket TCP 简单聊天的实现
- UDP实现简单聊天程序
- Delphi简单TCP聊天程序(三):登录注册功能
- 简单的Tcp点对点聊天程序
- 基于java利用JDOM读取XML文件实现简单留言簿程序
- 利用java实现一个简单的远程监控程序
- 用UDP实现可靠文件传输,如何利用UDX创建一个简单的WIN32程序
- android客户端简单的聊天程序实现
- Socket通讯编程实现简单的任意聊天程序
- 使用UDP实现一个简单的聊天程序。
- 利用socket实现简易聊天程序