最近学到了Socket通信,其实在学校的课程--计算机网络,这个东西是必学的。。。只是自己上课没听,只为应付考试,这个也没怎么碰触。接触到这个,现在就讲一下最简单的聊天通信C/S模式的代码的编写。
这里只谈一下最简单的C/S模式的聊天程序。
显然分为客户端和服务器端。
流程也很简单。服务端首先需要监听摸一个端口号。(由于1024以内的端口计算机通常内部程序在使用,所以我们最好监听端口号较大的。以8888为例。)
//监听端口号为8888端口
ServerSocket ss = new ServerSocket(8888);
//等待客户端的访问
Socket socket = ss.accept();
这个时候客户端访问该端口
Socket socket = new Socket("localhost",8888);
或者:
Socket socket = new Socket("127.0.0.1",8888);
这个时候两者的连接已经建立。
怎么交换信息呢?在Socket中,无论是客户端还是服务器都是从socket.getInputStream()中获取到对方的信息,而将自己需要发送的信息写入到socket.getOutputStream()中。
总结上面的也就是说,我们只需要建立连接,然后从socket.getInputStream()读取对方发送的信息,将自己需要发送的信息写入到socket.getOutputStream()中去快递给对方。
再谈谈多线程。
当需要启动多个客户端时,客户端的编码部分是没有变化的。只需要改变服务器端。
我们来观察整个通信过程,发现服务器端等待客户端接入时,执行ss.accept()来接受到客户端的Socket。但是当启动第二个时,就没有执行ss.accept()了。所以我们需要无限循环来一直接受客户端的接入(因为不知道有多少个客户端,所以就一直循环)。然后启动线程进行消息的接受与发送。(写一个线程类,重写run方法,将之前的接受与发送消息的代码直接复制就行了)
具体代码如下:
服务器:
单线程:
这里只谈一下最简单的C/S模式的聊天程序。
显然分为客户端和服务器端。
流程也很简单。服务端首先需要监听摸一个端口号。(由于1024以内的端口计算机通常内部程序在使用,所以我们最好监听端口号较大的。以8888为例。)
//监听端口号为8888端口
ServerSocket ss = new ServerSocket(8888);
//等待客户端的访问
Socket socket = ss.accept();
这个时候客户端访问该端口
Socket socket = new Socket("localhost",8888);
或者:
Socket socket = new Socket("127.0.0.1",8888);
这个时候两者的连接已经建立。
怎么交换信息呢?在Socket中,无论是客户端还是服务器都是从socket.getInputStream()中获取到对方的信息,而将自己需要发送的信息写入到socket.getOutputStream()中。
总结上面的也就是说,我们只需要建立连接,然后从socket.getInputStream()读取对方发送的信息,将自己需要发送的信息写入到socket.getOutputStream()中去快递给对方。
再谈谈多线程。
当需要启动多个客户端时,客户端的编码部分是没有变化的。只需要改变服务器端。
我们来观察整个通信过程,发现服务器端等待客户端接入时,执行ss.accept()来接受到客户端的Socket。但是当启动第二个时,就没有执行ss.accept()了。所以我们需要无限循环来一直接受客户端的接入(因为不知道有多少个客户端,所以就一直循环)。然后启动线程进行消息的接受与发送。(写一个线程类,重写run方法,将之前的接受与发送消息的代码直接复制就行了)
具体代码如下:
服务器:
单线程:
package 群聊; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.ServerSocket; import java.net.Socket; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class Server { JTextArea jtx_output; JTextArea jtx_input; InputStream input; OutputStream output; /** * 群聊服务器 * @param args * @throws MalformedURLException */ public static void main(String[] args) throws MalformedURLException { // TODO 自动生成的方法存根 new Server().showUI(); } public void showUI() throws MalformedURLException { JFrame jf = new JFrame(); jf.setTitle("群聊服务器"); jf.setSize(new Dimension(420, 480)); jf.setResizable(false);// 设置窗体大小不能改变 jf.setLocationRelativeTo(null); jf.setDefaultCloseOperation(3); JPanel jpL = new JPanel(); jpL.setPreferredSize(new Dimension(300, 400)); JPanel jpR = new JPanel(); jpR.setPreferredSize(new Dimension(100, 400)); //设置带自动换行的只读文本区域 jtx_output = new JTextArea(); //不可编辑,只读文本 jtx_output.setEditable(false); //jtx_input.setLineWrap(true); JScrollPane sp1 = new JScrollPane(jtx_output); sp1.setPreferredSize(new Dimension(300, 315)); jpL.add(sp1); //设置头像显示按钮 JButton jb = new JButton(new ImageIcon("images/头像1.jpg")); jpR.add(jb); //设置可输入自动换行的文本区域 jtx_input = new JTextArea(); // jtx_input.setLineWrap(true); JScrollPane sp2 = new JScrollPane(jtx_input); sp2.setPreferredSize(new Dimension(300, 100)); jpL.add(sp2); //设置头像显示按钮 JButton jb1 = new JButton(new ImageIcon("images/头像.JPEG")); jpR.add(jb1); JButton Jb = new JButton("发送"); jf.add(jpL, BorderLayout.WEST); jf.add(jpR, BorderLayout.EAST); jf.add(Jb, BorderLayout.SOUTH); jf.setVisible(true); // 新建一个服务器套接字 try { ServerSocket ss = new ServerSocket(8888); System.out.println("监听端口8888成功!"); jtx_output.append("监听端口8888成功!"); // 等待客户端的访问 Socket socket = ss.accept(); input = socket.getInputStream(); output = socket.getOutputStream(); //点击发送按钮,将服务器端的消息发送到客户端 Jb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String out = jtx_input.getText()+"\n"; jtx_output.append("服务器说 :"+out); //将服务器段的消息发送给客户端 try { byte[] bytes = out.getBytes("GBK"); try { output.write(bytes); output.flush(); } catch (IOException e1) { } } catch (UnsupportedEncodingException e1) { } } }); // String msg = "Hello, 你好!聊天开始!"; // jtx_output.append(msg); // //写到客户端 // byte[] bytes = msg.getBytes("GBK"); // output.write(bytes); //接受客户端发来的消息 while (true) { String line = readLine(input); jtx_output.append("客户端说 :"+line+"\n"); } } catch (IOException e) { } } // 用来读取中文的方法 public String readLine(InputStream input) throws IOException { // 字节输出流 ByteArrayOutputStream bos = new ByteArrayOutputStream(); while (true) { int n = input.read(); // 以换行符为读取的间隔 if (n == '\n') break; bos.write(n); } byte[] bytes = bos.toByteArray(); return new String(bytes, "GBK"); } } 多线程: (1)主类 package 群聊; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.ServerSocket; import java.net.Socket; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class ServerThread { JTextArea jtx_output; JTextArea jtx_input; /** * 群聊服务器多线程 * @param args * @throws MalformedURLException */ public static void main(String[] args) throws MalformedURLException { // TODO 自动生成的方法存根 new ServerThread().showUI(); } public void showUI() throws MalformedURLException { JFrame jf = new JFrame(); jf.setTitle("群聊服务器"); jf.setSize(new Dimension(420, 480)); jf.setResizable(false);// 设置窗体大小不能改变 jf.setLocationRelativeTo(null); jf.setDefaultCloseOperation(3); JPanel jpL = new JPanel(); jpL.setPreferredSize(new Dimension(300, 400)); JPanel jpR = new JPanel(); jpR.setPreferredSize(new Dimension(100, 400)); //设置带自动换行的只读文本区域 jtx_output = new JTextArea(); // 不可编辑,只读文本 jtx_output.setEditable(false); // jtx_input.setLineWrap(true); JScrollPane sp1 = new JScrollPane(jtx_output); sp1.setPreferredSize(new Dimension(300, 315)); jpL.add(sp1); // 设置头像显示按钮 JButton jb = new JButton(new ImageIcon("images/头像1.jpg")); jpR.add(jb); // 设置可输入自动换行的文本区域 jtx_input = new JTextArea(); // jtx_input.setLineWrap(true); JScrollPane sp2 = new JScrollPane(jtx_input); sp2.setPreferredSize(new Dimension(300, 100)); jpL.add(sp2); // 设置头像显示按钮 JButton jb1 = new JButton(new ImageIcon("images/头像.JPEG")); jpR.add(jb1); JButton Jb = new JButton("发送"); jf.add(jpL, BorderLayout.WEST); jf.add(jpR, BorderLayout.EAST); jf.add(Jb, BorderLayout.SOUTH); jf.setVisible(true); int i=0; // 新建一个服务器套接字 try { ServerSocket ss = new ServerSocket(8888); jtx_output.append("监听端口8888成功!\n"); // 循环多个客户端访问 while (true) { i++; // 接受到客户端的访问 Socket socket = ss.accept(); // 启动线程来搭建和该客户端的连接 SocketThread st = new SocketThread(socket,Jb,jtx_input,jtx_output,i); st.start(); } } catch (IOException e) { } } } (2)线程类 package 群聊; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.Socket; import javax.swing.JButton; import javax.swing.JTextArea; public class SocketThread extends Thread { public Socket socket; InputStream input; OutputStream output; int i; JButton Jb; JTextArea jtx_output; JTextArea jtx_input; // 构造方法传递客户端的socket public SocketThread(Socket scoket, JButton Jb, JTextArea jtx_input, JTextArea jtx_output, int i) { this.socket = scoket; this.Jb = Jb; this.jtx_input = jtx_input; this.jtx_output = jtx_output; this.i = i; } // 重写线程run方法 public void run() { try { input = socket.getInputStream(); } catch (IOException e2) { } try { output = socket.getOutputStream(); } catch (IOException e2) { } String outsay = "客户端" + i + "你好!"+"\n"; byte[] bytess; try { bytess = outsay.getBytes("GBK"); output.write(bytess); } catch (UnsupportedEncodingException e3) { // TODO 自动生成的 catch 块 e3.printStackTrace(); } catch (IOException e1) { // TODO 自动生成的 catch 块 e1.printStackTrace(); } // 点击发送按钮,将服务器端的消息发送到客户端 Jb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String out = jtx_input.getText() + "\n"; jtx_output.append("服务器说 :" + out+"\n"); // 将服务器段的消息发送给客户端 try { byte[] bytes = out.getBytes("GBK"); try { output.write(bytes); output.flush(); } catch (IOException e1) { } } catch (UnsupportedEncodingException e1) { } catch (IOException e2) { e2.printStackTrace(); } } }); // 接受客户端发来的消息 while (true) { try { String line = readLine(input); jtx_output.append("客户端" + i + "说 :" + line + "\n"); } catch (IOException e1) { } } } // 用来读取中文的方法 public String readLine(InputStream input) throws IOException { // 字节输出流 ByteArrayOutputStream bos = new ByteArrayOutputStream(); while (true) { int n = input.read(); // 以换行符为读取的间隔 if (n == '\n') break; bos.write(n); } byte[] bytes = bos.toByteArray(); return new String(bytes, "GBK"); } } 客户端: package 群聊; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.ServerSocket; import java.net.Socket; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; public class Client { JTextArea jtx_output; JTextArea jtx_input; InputStream input; OutputStream output; /** * @param args * @throws MalformedURLException */ public static void main(String[] args) throws MalformedURLException { // TODO 自动生成的方法存根 new Client().showUI(); } public void showUI() throws MalformedURLException { JFrame jf = new JFrame(); jf.setTitle("群聊客户器"); jf.setSize(new Dimension(420, 480)); jf.setResizable(false);// 设置窗体大小不能改变 jf.setLocationRelativeTo(null); jf.setDefaultCloseOperation(3); JPanel jpL = new JPanel(); jpL.setPreferredSize(new Dimension(300, 400)); JPanel jpR = new JPanel(); jpR.setPreferredSize(new Dimension(100, 400)); // 设置带自动换行的只读文本区域 jtx_output = new JTextArea(); // 不可编辑,只读文本 jtx_output.setEditable(false); // jtx_input.setLineWrap(true); JScrollPane sp1 = new JScrollPane(jtx_output); sp1.setPreferredSize(new Dimension(300, 315)); jpL.add(sp1); // 设置头像显示按钮 JButton jb = new JButton(new ImageIcon("管理员")); jpR.add(jb); // 设置可输入自动换行的文本区域 jtx_input = new JTextArea(); // jtx_input.setLineWrap(true); JScrollPane sp2 = new JScrollPane(jtx_input); sp2.setPreferredSize(new Dimension(300, 100)); jpL.add(sp2); // 设置头像显示按钮 JButton jb1 = new JButton(new ImageIcon("images/头像.JPEG")); jpR.add(jb1); JButton Jb = new JButton("发送"); jf.add(jpL, BorderLayout.WEST); jf.add(jpR, BorderLayout.EAST); jf.add(Jb, BorderLayout.SOUTH); jf.setVisible(true); // 新建一个服务器套接字 try { Socket ss = new Socket("127.0.0.1",8888); input = ss.getInputStream(); output = ss.getOutputStream(); Jb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String out = jtx_input.getText()+"\n"; jtx_output.append("客户端说:"+out+"\n"); //将服务器段的消息发送给客户端 try { byte[] bytes = out.getBytes("GBK"); output.write(bytes); } catch (IOException e1) { e1.printStackTrace(); } } }); //接受服务器端发来的消息 while (true) { String line = readLine(input); jtx_output.append("服务器说 :"+line+"\n"); } } catch (IOException e) { e.printStackTrace(); } } // 用来读取中文的方法 public String readLine(InputStream input) throws IOException { // 字节输出流 ByteArrayOutputStream bos = new ByteArrayOutputStream(); while (true) { int n = input.read(); // 以换行符为读取的间隔 if (n == '\n') break; bos.write(n); } byte[] bytes = bos.toByteArray(); return new String(bytes, "GBK"); } }
相关推荐
Java的Socket通信是基于网络编程的一种技术,它允许两个进程在不同的计算机上通过网络进行数据交换。这种通信方式通常用于构建客户端-服务器架构的应用程序。在Java中,Socket通信涉及到两种类型的Socket:...
Java Socket 是一种网络通信协议,它是Java编程语言中实现客户端-服务器模型的基础。Socket 提供了低级别的、面向连接的、双向通信的网络接口,允许应用程序通过网络进行数据传输。在本示例中,我们将深入探讨Java ...
Java和C++之间的Socket通信是跨语言网络编程的一个常见应用场景,尤其在系统集成、设备通讯或者混合编程中。Socket提供了一种基于TCP/IP协议的进程间通信(IPC)方式,可以实现在不同操作系统上的进程之间的数据传输...
Java Socket通信是网络编程中的基础概念,主要用于两个应用程序之间的双向通信。在这个"Java_socket 通信示例"中,我们看到的是一个简单的聊天室应用,它利用了Java的Socket API来实现实时的数据交换。以下是对这个...
本示例聚焦于Node.js与Java之间的Socket通信,这是一个非常实用的技术,因为这两种技术在Web开发和后端服务中都占据着重要的地位。让我们详细探讨一下如何实现Node.js与Java的Socket通信。 首先,Socket是一种基于...
本话题主要探讨了两种常用编程语言——Java和C#之间如何利用Socket进行通信。Socket是网络编程的基本接口,允许应用程序通过网络发送和接收数据。以下是关于"Java和C#之间基于Socket的通信"的详细知识点: 1. **...
Java Socket通信是网络编程中的重要一环,它提供了在两台计算机之间建立低级连接的能力,使得它们可以相互通信。在这个"java上socket通信即时通信界面本"中,我们很显然关注的是如何使用Java来构建一个具有图形用户...
Java实现的简单Socket通信是网络编程中的基础技术,主要用于设备间的双向数据传输。在这个场景中,我们有两个窗口,一个作为服务器端,另一个作为客户端,它们通过TCP协议进行通信。TCP是一种面向连接的、可靠的传输...
Java Socket通信实现是一种基于TCP/IP协议的网络通信方式,它允许两台计算机通过互联网进行双向数据传输。在Java中,Socket类和ServerSocket类是实现客户端-服务器模型通信的核心工具。下面将详细介绍Java Socket...
基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java Socket通信实现.zip 基于java的开发源码-Java ...
本教程将详细解释如何在Android中实现Java和C的Socket通信,特别是在涉及文件描述符传递的场景下。 1. **Java Socket基础** Java中的`java.net.Socket`类提供了网络通信的能力,它允许我们在两个应用程序之间建立...
基于java的开发源码-Socket 聊天通信演示代码.zip 基于java的开发源码-Socket 聊天通信演示代码.zip 基于java的开发源码-Socket 聊天通信演示代码.zip 基于java的开发源码-Socket 聊天通信演示代码.zip 基于java的...
在IT领域,网络通信是不可或缺的一部分,而Java作为一种强大的编程语言,提供了丰富的API来支持网络编程,特别是通过Socket实现客户端/服务器(C/S)架构的即时通信系统。本项目"基于Java实现的socket即时通信系统...
Java Socket通信实现是Java网络编程中的重要组成部分,它允许两台计算机通过TCP/IP协议进行双向通信。在Java中,Socket提供了低级别的、基于连接的、面向数据流的通信API,可以用于实现客户端-服务器架构的应用程序...
Java中的Socket通信是一种基于TCP/IP协议的网络编程方式,它允许两台计算机通过网络进行双向通信。在本项目中,“基于socket通信的javaDH通信实现”是利用Java语言实现的一种安全通信机制,其中融入了Diffie-Hellman...
用java实现socket通信,界面可视化,有服务端和客户端
SpringMVC的Socket实现+Java Tomcat websocket实现+Java Socket通信实现 +Java UDP通信实现。websocket_study.rar 为springMVC版本的socket实现 websocket02.rar 里面包含tomcat的websocket实现+java socket双向通信...
Socket通信技术是Java编程环境中实现网络通信的一种基础方式,它基于TCP/IP协议栈,允许两台计算机通过网络进行数据交换。TCP(传输控制协议)是一种面向连接的、可靠的传输协议,确保了数据的顺序和完整性。 在...
Java Socket通信实现是Java网络编程中的重要组成部分,它允许两个应用程序通过网络进行双向通信。Socket在TCP/IP协议栈中扮演着客户端与服务器端交互的角色,提供了低级别的、面向连接的、可靠的字节流通信。本代码...