网络编程;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();
}
}
}
}