网络编程
实现网络互连的不同计算机上运行的程序间可以进行
数据交换。
-
计算机网络由一些相互连接的、自治的计算机组成的集合
-
网络编程的概念
-
网络七层结构(五层结构)
-
网络通信三要素
-
ip(计算机标识)
-
端口(计算机上不同服务的标识)
-
协议
-
UDP
-
不面向连接 不可靠
-
-
TCP
-
面向连接的 可靠的(三次握手)
-
-
-
public static void main(String[] args) throws UnknownHostException {
InetAddress inetAddress =InetAddress.getByName("LAPTOP-70SMTMJN");
//
System.out.println(inetAddress);
//获取主机名称
String hostName = inetAddress.getHostName();
System.out.println(hostName);
//获取主机IP地址
String hostAddress = inetAddress.getHostAddress();
System.out.println(hostAddress);
}
Socket通信
- Socket套接字:
-
网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
-
通信原理:
-
数据在两个Socket间通过IO传输
-
-
socke常见构造函数:
-
API是个宝贝
-
-
Socket常见方法:
-
getOutputStream() 返回此套接字的输出流
-
-
-
TCP协议开发(面向连接,可靠协议)
-
基本通讯
-
/*----------------服务器端-----------------------*/
//创建出服务器Scoket对象
ServerSocket serverSocket =new ServerSocket(8888);
System.out.println("服务器启动成功");
//服务器应该时刻知道客户端是否连接
Socket socket =serverSocket.accept();
//读取客户端数据
DataInputStream in =new DataInputStream(socket.getInputStream());
System.out.println(in.readUTF());
//写数据
DataOutputStream out =new DataOutputStream(socket.getOutputStream());
out.writeUTF("服务器:客户端你好");
/*----------------客户端-----------------------*/
Socket socket =new Socket("localhost",8888);
//客户端写数据
DataOutputStream out =new DataOutputStream(socket.getOutputStream());
out.writeUTF("客户端说:服务器你好");
DataInputStream in =new DataInputStream(socket.getInputStream());
System.out.println(in.readUTF());
-
案例_一对一聊天
-
添加线程,让用户在聊天的时候不需要等待对方回复也是可以成功发送消息
-
将服务器与客户端的读与写全部加上while(true)死循环
-
/**
* @Auther: etc
* @Date: 2019/8/5 10:27
* @Description: 服务器端
*
* **如果客户端连不上服务器,那就去看看别人能不能ping通你
* 如果不能可能是防火墙限制了,关掉就好
* 如果可以,那就很有可能是端口被占用了,改一下端口号
*
*
*/
public class Sever
{
public static Scanner sc =new Scanner(System.in);
public static void main(String[] args) throws IOException
{
//创建出服务器serverSocket对象
ServerSocket serverSocket =new ServerSocket(10010);
System.out.println("服务器启动成功");
//服务器应该时刻知道客户端是否连接
Socket socket =serverSocket.accept();
SeverThread severThread =new SeverThread(socket);
severThread.start();
while(true)
{
//写数据
DataOutputStream out =new DataOutputStream(socket.getOutputStream());
out.writeUTF("服务器:"+sc.next());
}
}
}
//单读读取数据的线程
class SeverThread extends Thread
{
private Socket socket;
public SeverThread(Socket socket)
{
this.socket=socket;
}
@Override
public void run() {
//读取客户端数据
try {
while (true) {
DataInputStream in = new DataInputStream(socket.getInputStream());
System.out.println(in.readUTF());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*---------------------------------------------------------------------------*/
/**
* @Auther: etc
* @Date: 2019/8/5 10:54
* @Description:
*/
public class Client
{
public static Scanner sc =new Scanner(System.in);
public static void main(String[] args) throws IOException
{
Socket socket =new Socket("192.168.28.38",10010);
ClientThread clientThread=new ClientThread(socket);
clientThread.start();
while (true)
{
//客户端写数据
DataOutputStream out =new DataOutputStream(socket.getOutputStream());
out.writeUTF("客户端:"+sc.nextLine());
}
}
}
class ClientThread extends Thread
{
private Socket socket;
public ClientThread(Socket socket)
{
this.socket=socket;
}
@Override
public void run() {
try {
while(true)
{
DataInputStream in = new DataInputStream(socket.getInputStream());
System.out.println(in.readUTF());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
-
案例_群聊
-
客户端代码依旧不变
-
服务器代码修改:
-
使用socketList .add(socket)来记录连接的对象,一个客户端对应一个对象
-
客户端之间发送消息:遍历集合 socketList(使用泛型),如果对应的 Socket不是自己的,那就转发消息
-
-
/**
* @Auther: etc
* @Date: 2019/8/5 10:27
* @Description: 服务器端
*/
public class Sever
{
public static Scanner sc =new Scanner(System.in);
//服务器应该时刻知道客户端是否连接
public static List<Socket> socketList =new ArrayList<Socket>();
public static void main(String[] args) throws IOException
{
//创建出服务器serverSocket对象
ServerSocket serverSocket =new ServerSocket(8886);
System.out.println("服务器启动成功");
while (true)
{
//接受此套接字的链接
Socket socket = serverSocket.accept();
//将客户添加到集合中
socketList.add(socket);
//在线人数
System.out.println("在线人数:"+socketList.size());
//创建线程对象 ,多少个客户端就多少个对象
SeverThread severThread =new SeverThread(socket);
severThread.start();
//写数据
DataOutputStream out =new DataOutputStream(socket.getOutputStream());
out.writeUTF("服务器:"+sc.next());
}
}
}
//读取数据的线程 将某个客户端的消息发送给其他客户端
class SeverThread extends Thread
{
private Socket socket;
public SeverThread(Socket socket)
{
this.socket=socket;
}
@Override
public void run() {
//读取客户端数据
try {
while (true) {
DataInputStream in = new DataInputStream(socket.getInputStream());
String msg =in.readUTF();
//System.out.println(in.readUTF());
//遍历集合如果不是自己,就把消息发送
for (Socket client : Sever.socketList)
{
if(socket!=client )
{
DataOutputStream out = new DataOutputStream(client.getOutputStream());
out.writeUTF(msg);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
-
UDP协议开发
-
无连接的,不可靠的协议
-
UDP通信思路:
-
A: 创建发送端 Socket 对象
-
B: 创建数据,并把数据打包
-
C: 调用 Socket 对象的发送方法发送数据包
-
D: 释放资源
-
-
发送和接收都是使用 DatagramSocket
-
/*---------------接收-------------------*/
/**
* @Auther: etc
* @Date: 2019/8/5 15:20
* @Description: 接收包
*/
public class Receive
{
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket =
new DatagramSocket(10010, InetAddress.getByName("localhost"));
//存放数据的容器
byte[] buf =new byte[1024];
//接收到的数据包
DatagramPacket packet =new DatagramPacket(buf,buf.length);
datagramSocket.receive(packet);
//输出数据包内容
String str =new String (buf);
System.out.println(str);
}
}
/*--------------发送--------------------*/
/**
* @Auther: etc
* @Date: 2019/8/5 15:19
* @Description:
*/
public class Sent
{
public static void main(String[] args) throws IOException {
DatagramSocket send =
new DatagramSocket(10086, InetAddress.getByName("localhost"));
//要发送的内容
String str="hello";
//发送数据包
DatagramPacket packet =new DatagramPacket(
str.getBytes(),
str.getBytes().length,
InetAddress.getByName("localhost"),
10010);
send.send(packet);
}
}