网络编程;TCP/IP协议
网络:实现计算机之间的信息共享,数据资源的交换
协议:数据交换需要遵守的一种协议,按照约定的数据格式等写出去
端口:用于计算机之间的通信
每运行一个程序,系统会分配一个编号给该程序,作为和外界交换数据的唯一标识
0~65535
查看被使用的端口
在命令行运行netstat -ano
C/S模式:客户端和服务器共同承担计算机的体系结构
优点;a,分别负责不同的工作,快速的进行数据的传递
b,服务器可同时为数千台的客户端进行服务
c,多个客户端可以同时访问该服务器
IP 终端设备在网络中的唯一编号
查看IP
在命令行运行ipconfig
本机Ip的表示方式:localhost 127.0.0.1
万维网 公网
局域网 内网
IP地址:分为A,B,C,D四类,每个IP地址分为四个8位字节
A类:1.0.0.0到127.0.0.0
B类:128.0.0.0到 191.255.0.0
C类;192.0.0.0到 223.255.255.0
D类;224.0.0.0到 254.0.0.0
DNS;域名 将IP地址转化为一个标识
InetAddress:封装IP地址和端口
Socket
此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
常用:
构造方法摘要
Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字 |
|
Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 |
方法摘要
InetAddress |
getInetAddress() 返回套接字连接的地址。 |
InputStream |
getInputStream() 返回此套接字的输入流。 |
InetAddress |
getLocalAddress() 获取套接字绑定的本地地址。 |
OutputStream |
getOutputStream() 返回此套接字的输出流。 |
java.net
类 ServerSocket
此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
构造方法摘要
ServerSocket(int port)
创建绑定到特定端口的服务器套接字。
方法摘要
Socket |
accept() 侦听并接受到此套接字的连接。 |
InetAddress |
getInetAddress() 返回此服务器套接字的本地地址。 |
使用InetAddress来测试
package com.network.com; import java.net.Inet4Address; import java.net.InetAddress; public class InetAddressDemo { public static void main(String[] args) { try { //获得本机的地址 InetAddress LocalHost= InetAddress.getLocalHost(); System.out.println(LocalHost); //根据机器名获得相应的主机名 InetAddress name= InetAddress.getByName("127.0.0.1"); System.out.println(name); //通过域名获得主机名 InetAddress name1= InetAddress.getByName("www.baidu.com"); System.out.println(name1); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
运行结果:
baihe/192.168.43.229
/127.0.0.1
www.baidu.com/61.135.169.105
显示群聊的
package 聊天Server; /** * 服务器界面 */ import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class SreverDemo { public static ArrayList<Socket> list = new ArrayList<Socket>(); public static void main(String[] args) { try { // 创建服务器套接字 ServerSocket server = new ServerSocket(6060); System.out.println("等待链接:"); while(true){ // 等待客户端的链接 Socket socket = server.accept(); // 输出连接到的ip和端口 System.out.println("连接上" + socket.getLocalSocketAddress() + socket.getRemoteSocketAddress()); //创建线程对象 SreverDemoThread thread = new SreverDemoThread(socket); //启动线程 thread.start(); list.add(socket); } } catch (IOException e) { e.printStackTrace(); } } }
package 聊天Server; /** * 服务器线程的输入输出 */ import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.Socket; import java.util.ArrayList; public class SreverDemoThread extends Thread { private Socket socket; public SreverDemoThread(Socket socket) { this.socket = socket; } @Override public void run() { try { // 从Socket上获得输出流对象 OutputStream out = socket.getOutputStream(); // 包装成字符输出流 OutputStreamWriter writer = new OutputStreamWriter(out); // 包装成缓冲字符输出流 BufferedWriter bis = new BufferedWriter(writer); bis.write(socket.getRemoteSocketAddress() + "等待输出:" + "\r\n"); bis.flush(); // 获得输入流 InputStream isr = socket.getInputStream(); // 包装成字符输入流 InputStreamReader reader = new InputStreamReader(isr); // 包装成缓冲字符流 BufferedReader read = new BufferedReader(reader); // 每次读取一行 String str = read.readLine(); while (str != null) { System.out.println("说:" + str); // 遍历队列 for (int i = 0; i < SreverDemo.list.size(); i++) { // 取出队列中的个数 Socket sc = SreverDemo.list.get(i); if (sc != socket) { // 输出给其它的客户端,先获得该客户端上的套接字 OutputStream ptm = sc.getOutputStream(); // 包装成缓冲字符串 BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(ptm)); // 输出 bw.write(str + "\r\n"); System.out.println(socket.getRemoteSocketAddress() + "输出:" + str); bw.flush(); } } str = read.readLine(); } } catch (Exception e) { System.out.println(socket.getRemoteSocketAddress() + ":客户端已经退出"); } } }
客户端
package qqclient; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTextArea; /** * 客户端界面 * * @author Administrator * */ public class ChatclientUI extends JFrame { // 属性 private JTextArea areaSend; private BufferedWriter bw; private BufferedReader br; private JTextArea area; private InetAddress name; // 主函数 public static void main(String[] args) { new ChatclientUI(); } // 构造方法 public ChatclientUI() { intitUI(); Send(); ChatClientThread th = new ChatClientThread(br, area); th.start(); } // 创建界面的方法 public void intitUI() { this.setTitle("聊天室"); this.setSize(500, 400); // 设置关闭方式 this.setDefaultCloseOperation(3); // 设置布局 this.setLayout(new FlowLayout()); // 禁止改变大小 this.setResizable(false); // 消息区域 // 设置多行文本 area = new JTextArea(); area.setPreferredSize(new Dimension(480, 200)); // 设置背景颜色 area.setBackground(Color.lightGray); // 设置字体颜色 area.setForeground(Color.green); JScrollPane pallSend = new JScrollPane(area); // 设置自动滚动 pallSend.setAutoscrolls(true); this.add(pallSend); // 消息发送区域 areaSend = new JTextArea(); areaSend.setPreferredSize(new Dimension(480, 100)); // 设置字体颜色 areaSend.setForeground(Color.blue); // 设置滚动区域 JScrollPane sendPall = new JScrollPane(areaSend); this.add(sendPall); // 设置按钮 JButton btn = new JButton("发送"); this.add(btn); LisAction lis = new LisAction(); btn.addActionListener(lis); // 设置窗体显示 this.setVisible(true); } /** * 创建客户端输入输出的方法 */ public void Send() { try { // 创建客户端 Socket socket = new Socket("127.0.0.1", 6060); name = socket.getInetAddress().getLocalHost(); // 输入输出 InputStream isr = socket.getInputStream(); OutputStream ops = socket.getOutputStream(); // 包装成缓冲输入输出流 br = new BufferedReader(new InputStreamReader(isr)); bw = new BufferedWriter(new OutputStreamWriter(ops)); } catch (Exception e) { System.out.println(name + "未连接上服务器"); } } // 创建监听器 class LisAction implements ActionListener { @Override public void actionPerformed(ActionEvent e) { String mm = areaSend.getText().trim() + "\r\n"; if ("".equals(mm) || " ".equals(mm)) { } else { try { // 将字符串写出 bw.write(name + ": " + getTime() + "\r\n" + mm); bw.flush(); // 清空 areaSend.setText(""); // 显示在消息区域 area.append(name + ": " + getTime() + "\r\n" + mm); } catch (IOException e1) { e1.printStackTrace(); } } } } // 获得当前时间的方法 public String getTime() { long time = System.currentTimeMillis(); Date date = new Date(time); SimpleDateFormat ailm = new SimpleDateFormat("y/M/d HH:mm:ss"); return ailm.format(date); } }
package qqclient; import java.io.BufferedReader; import java.io.IOException; import javax.swing.JTextArea; /** * 创建客户端线程读取 * @author Administrator * */ public class ChatClientThread extends Thread{ private BufferedReader br; private JTextArea area; private boolean islive = true; public ChatClientThread(BufferedReader br,JTextArea area){ this.br = br; this.area = area; } @Override public void run() { while(islive){ try { String mm = br.readLine(); area.append(mm+"\r\n"); } catch (IOException e) { area.append("服务器连接失败"+"\r\n"); e.printStackTrace(); } } } }