Java基础练习 — 网络编程

一、 网络编程

1.1 Socket(套接字)

  1. Socket套接字:用于描述IP地址和端口,是一个通信链的句柄。在Internet上的主机一般运行了多个服务软件,同时提供了集中服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。
  2. Socket就是为网络编程提供的一种机制;通信的两端都有Socket;网络通信其实就是Socket间的通信,数据在2个Socket间通过IO传输。

1.2 网络通信的3要素

  1. IP地址:网络中的设备标识,不易记忆,可用主机名。
  2. 端口号:用于标识进程的逻辑地址,不同进程有不同的标识。
  3. 传输协议:通讯的规则,常见协议:TCP,UDP

1.3 端口号

  1. 物理端口:网卡口。
  2. 逻辑端口:每个网络程序都至少有一个逻辑端口,用于标识程序的逻辑地址,不同进程的标识。有效端口:0~65535,其中0 ~1024系统使用或保留端口(可用360)查看。

1.4 协议

UDP协议:

  1. 将数据源和目的地封装在数据包中,不需要建立连接。
  2. 每个数据包的大小限制在64k。
  3. 因无连接,是不可靠的协议。
  4. 不需要建立连接,速度更快。

TCP协议:

  1. 建立连接,形成传输数据的通道。
  2. 在连接中进行大数量的传输。
  3. 通过3次握手完成连接,是可靠的连接。(1. 客户端问:你还活着吗?2. 服务器回:我还活着!3. 连接)
  4. 必须建立连接,效率会稍低。

二、InetAddress

此类表示互联网协议(IP)地址。

  1. static InetAddress getByName(String host):在给定主机名的情况下确定主机的IP地址。

代码示例

InetAddress address = InetAddress.getByName("小男孩的PC"); //小男孩的PC/169.234.37.34
/*InetAddress address = InetAddress.getByName("169.254.37.34");*/ //169.234.37.34
System.out.print(address);
String hostAddress = address.getHostAddress(); //返回IP地址
String hostName = address.getHostName(); //返回主机名
System.out.println(hostAddress);
System.out.println(hostName);

三、UDP

3.1 发送步骤

  1. 创建发送端Socket对象
  2. 创建数据并打包
  3. 发送数据
  4. 释放资源

3.2 方法

  1. DatagramSocket:此类表示用来发送和接收数据,基于UDP协议。
  2. DatagramSocket():创建Socket对象,并随机分配端口号。
  3. DatagramSocket(int port):创建Socket对象,并指定端口号。
  4. DatagramPacket:表示数据包。
  5. DatagramPacket(byte[] buf, int length, InetAddress address, int port):对数据进行打包,贴上物流单,单上信息有数据,长度,地址,端口。

发送端代码示例

1)创建发送端Socket对象
DatagramSocket ds = new DatagramSocket();
2)创建数据并打包
String s = "hello, UDP, im coming";
byte[] bys = s.getBytes();
int length = bys.length;
InetAddress address = InetAddress.getByName("小男孩的PC");
int port = 8888;
3)打包
DatagramPacket dp = new DatagramPacket(bys, length, address, port);
4)发送数据
ds.send(dp);
5)释放资源
ds.close();

接收端代码示例

1)创建接收端Socket对象
DatagramServer ds = new DatagramServer(8888); //必须与发送的端口一致
2)创建包对象(容器)
byte[] bys = new byte[1024]; //容器
DatagramPacket dp = new DataPacket(bys, bys.length);
ds.receive(dp); //阻塞
3)解析数据
InetAddress address = dp.getAddress();
byte[] data = dp.getData();
int length = dp.getLength();
4)输出数据
System.out.println("sender --->" + address.getHostAddress());
System.out.println(data, 0, length);
5)释放资源
ds.close();

3.3 UDP协议手法数据的注意事项

  1. 端口号错误,数据可以正常发出,不会出现异常,但是收不到数据。
  2. BindException:端口已经被占用了。

四、TCP

4.1 发送步骤

  1. 创建发送端Socket对象(创建连接)。
  2. 获取输出流对象。
  3. 发送数据。
  4. 释放资源

4.2 方法

  1. Socket(InetAddress address, int port):创建一个套接字,并将其连接到指定IP地址的指定端口号。

发送端代码示例

1)创建发送端Socket对象(创建连接)
Socket s = new Socket(InetAddress.getByName("小男孩的PC"), 10086);
2)获得输出流对象
OutputStream os = s.getOutputStream();
3)发送数据
String str = "hello TSP, im coming";
os.write(str.getBytes());
4)释放资源
os.close();

4.3 接收步骤

  1. 创建接收端Socket对象
  2. 监听(阻塞)
  3. 获取输入流对象
  4. 获取数据
  5. 输出数据
  6. 释放资源

4.4 方法

  1. ServerSocket:接收端,服务端Socket没有读写数据的方法,需要通过获取Socket来进行读写,监听就是获取Socket对象来进行读写。
  2. ServerSocket(int port):创建绑定到特定端口的服务器套接字。

接收端代码示例

1)创建服务端Socket对象
ServerSocket ss = new ServerSocket(10086);
2)监听(阻塞)
Socket s = ss.accept();
3)获取输入流对象
InputStream is = s.getInputStream();
4)获取数据
byte[] bys = new byte[1024];
int len;
len = is.read(bys);
InetAddress address = s.getInetAddress();
5)输出数据
System.out.println(address);
System.out.println(bys, 0, len);
6)释放资源
s.close();
//ss.close();//服务端可不关闭

4.5 案例一

需求:使用TCP协议发送数据,并将接收导的数据转换成大写返回。
客户端代码示例

//发出数据
Socket s = new Socket(InetAddress.getByName("小男孩的PC", 10010));
OutputStream os = s.getOutputStream();
os.write("tcpdemo".getBytes());
----------------------
//接收数据
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
len = is.read(bys);
System.out.println(new String(bys, 0, len));
s.close();

接收端代码示例

//接收数据
ServerSocket ss = new ServerSocket(10010);
Socket s = ss.accept();
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
len = is.read(bys);
String str = new String(bys, 0, len);
String upperStr = str.toUpperCase();
--------------------
//发送数据
OutputStream os = s.getOutputStream();
os.write(upperStr.getBytes());
s.close();

4.6 案例二

需求:模拟用户登陆

用户类

public class User{
	private String username;
	private int age;
	public User(String username, int age){
		super();
		this.username = username;
		this.age = age;
	}
	//getter and setter
	...
}

用户数据库类

public class User{
	public static list<User> users = new ArrayList<User>();
	static{
		users.add(new User("张三", 18));
		...
	}

	public static List<User> getUsers(){
		return users;
	}
}

客户端

//发出数据
Socket s = new Socket("小男孩的PC", 8888);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入用户名:");
String username = br.readLine();
System.out.println("请输入密码:");
String password = br.readLine();
/*BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));*/
PrintWriter out = new PrintWriter(s.getOutputStream(), true); //true表示可以自动换行
out.println(username);
out.println(password);
------------------------------
//接收数据
BufferedReader serverBr = new BufferedReader(new InputStreamWriter(s.getInputStream()));
String result = serverBr.readLine();
System.out.println(result);
s.close();

服务端

ServerSocket ss = new ServerSocket(8888);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String username = br.readLine();
String password = br.readLine();
boolean flag = false;
List<User> users = UserDB.getUsers();
User user = new User(username, password);
if(users.contains(user)){
	flag = true;
}
PrintWriter out = new PrintWriter(s.getOutputStream());
if(flag){
	out.println("登陆失败");
}else{
	out.println("登陆成功");
}
s.close();
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值