网络编程:在网络通信协议下,不同计算机上运行的程序,进行的数据传输
网络编程三要素
-
ip:设备在网络中的地址,是唯一标识
-
端口号:应用程序在设备中的唯一标识,取值范围:(0~65535)
其中0~1023之间的端口号用于一些知名的网络服务或者应用
我们自己使用1024以上的端口号就可以了
一个端口号只能被一个应用程序使用
-
协议:数据在网络中的传输和连接规则,常见的协议有:UDP,TCP,HTTP,HTTPS,FTP
InetAddress类
此类表示互联网协议(IP)地址
public class Test {
public static void main(String[] args) throws UnknownHostException {
//获取InetAddress对象
//其实就是IP对象,一台电脑对象
InetAddress address = InetAddress.getByName("ip地址,或者电脑主机名");
System.out.println(address);
String name = address.getHostName();
System.out.println("电脑主机名:"+name);
String ip = address.getHostAddress();
System.out.println("电脑ip:"+ip);
}
}
协议
-
UDP协议(用户数据报协议)
他是面向无连接的通信协议
速度快,有大小限制,一次是发送64K,数据不安全,易丢失
-
TCP协议(传输控制协议)
他是面向连接的通信协议
速度慢,没有大小限制,数据安全
UDP通信
-
发送数据
import java.io.IOException; import java.net.*; public class SendMessage { public static void main(String[] args) throws IOException { //1.创建DatagramSocket对象 //绑定端口:以后我们可以通过这个端口发送数据 //空参:所有可用端口中随机一个端口发送 //有参:指定端口绑定 DatagramSocket ds = new DatagramSocket(); //打包数据 String str = "你好,大美中国!!!!"; byte[] buff = str.getBytes(); InetAddress address = InetAddress.getByName("127.0.0.1"); int port = 10086; DatagramPacket dp = new DatagramPacket(buff, buff.length,address,port); //发送数据 ds.send(dp); //释放资源 ds.close(); } }
-
接受数据
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; public class ReceiveMessage { public static void main(String[] args) throws IOException { //创建对象 //在接受数据的时候一定要绑定端口,而且绑定的端口要与发送端口一致 DatagramSocket ds = new DatagramSocket(10086); //接受数据包 byte bytes[] = new byte[1024]; DatagramPacket dp = new DatagramPacket(bytes, bytes.length); /* *该方法是阻塞的 *程序运行到这里会死等,等发送端发送数据 */ ds.receive(dp); //解析数据包 byte[] data = dp.getData(); int length = dp.getLength(); InetAddress address = dp.getAddress(); int port = dp.getPort(); System.out.println("接受到的数据:" + new String(data,0,length)); System.out.println("该数据是从" + address + "这台电脑的" + port + "端口发送出来的"); //释放资源 ds.close(); } }
TCP通信
TCP通信协议是一种可靠的通信协议,它在通信两端各建立一个socket对象
通信之前要保证连接已经建立
通过socket产生IO流来进行网络通信
import java.io.IOException;
import java.io.OutputStream;
import java.net.DatagramSocket;
import java.net.Socket;
public class TcpClient {
public static void main(String[] args) throws IOException {
//发送数据
//创建socket对象
//创建对象的时候会连接服务端,如果连接不上,会报错
Socket socket = new Socket("127.0.0.1",10000);
//从连接通道中获取输出流
OutputStream os = socket.getOutputStream();
//写出数据
os.write("aaa".getBytes());
//释放资源
os.close();
socket.close();
}
}
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws IOException {
//接受数据
//创建ServerSocket对象
ServerSocket ss = new ServerSocket(10000);
//监听客户端的连接
Socket socket = ss.accept();
//从通道中获取输入流的数据
InputStream is = socket.getInputStream();
int b;
while((b=is.read()) != -1){
System.out.println((char)b);
}
socket.close();
ss.close();
}
}
注意:上述代码在发送中文过程中会出现乱码
原因:使用字节流来读取数据(一个字节一个字节的读取,会出现乱码问题)
修改:使用字符流或者缓冲字符流来读取数据
修改代码如下
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) throws IOException {
//接受数据
//创建ServerSocket对象
ServerSocket ss = new ServerSocket(10000);
//监听客户端的连接
Socket socket = ss.accept();
//从通道中获取输入流的数据
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
int b;
while((b=isr.read()) != -1){
System.out.println((char)b);
}
socket.close();
ss.close();
}
}