[网络编程学习及双人聊天实现]

本文深入探讨了网络编程基础,包括TCP和UDP协议的特点。讲解了Java中利用java.net包进行TCP与UDP编程的方法,如TCP的Socket和ServerSocket,UDP的DatagramSocket和DatagramPacket,并提供了简单的文件上传概念和示例。同时,文章以双人聊天应用为例,阐述了网络编程的实际应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


一.什么是网络编程?

示例:数据是通过网络进行传输的,分为B/S,C/S;

1.网络基础

网络就是将不同区域的计算机连接在一起,形成了局域网,城域网,互联网;
网络模型:
OSI:应用层,表示层、会话层、传输层、网络层、数据链路层、物理层;
常用的网络协议:
TCP协议:建立在连接的基础上。传输数据之前,客户端与服务端首先要建立连接。(建立连接:经过3次握手;1.客户端请求;2.服务端响应,转告客户端我已收到请求;3.客户端发送确认请求),(断开连接需要4次挥手),所以其提供的是可靠的数据传输,但传输速度有限,是端到端的传输。
UDP协议:无连接,发送数据直接发,不管对方是否收到,也不确保是否安全;是不可靠的数据传输协议,但传输速度快;支持一对一,一对多,多对多。
IP:IP地址:网络上的主机的唯一标识;
端口号:对软件的逻辑标识,系统都会默认分配一个端口号,程序也可以自己指定端口号0-65535,其中0-1024已经被占用;

二、编程jdk —java.net

1.TCP编程

客户端: Socket此类实现客户端套接字。套接字是两台机器间通信的端点,操作的是字符流;
方法:Socket(String host,int port)创建一个流套接字并将其连接到指定主机上的指定端口号。
InputStream getInputStream()返回此套接字的输入流。
OutputStream getOutputStream() 返回此套接字的输出流。
void shutdownOutput() 禁用此套接字的输出流。对于TCP套接字,任何以前写入的数据都将被发送,并且后跟TCP的正常连接终止序列;
void close() 关闭此套接字。
服务端: 其需要先 启动,否则客户端会报异常ConnectException;ServerSocket 此类实现服务器套接字。服务器套接字等待请求通过网络传入。
ServerSocket(int port)创建绑定到特定端口的服务器套接字。此方法在连接传入之前一直阻塞。
Socket appept()侦听并接收到此套接字的连接。服务器端没有它字节的字节流,所以使用客户端的流和相应的客户端进行交互。
void close() 关闭此套接字。

2.文件上传:

分析步骤:Client---------------Server
Client
文件:
1、把文件读到内存 FileInputStream
2、内存通过网洛传输到Server OutputStream
Server
1、读Socket InputStream
2、写入文件 FileOutputStream

代码如下(示例):

package Practice1.ddd;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(7878);//创建serversocket对象,并声明端口号
		while(true) {//服务器时刻在监听,等待上传。
			Socket client = server.accept();//设置监听;
			InputStream is = client.getInputStream();//读写操作
			File dir = new File("D:/uplode/picture");
			if(!dir.exists()) {//创建固定目录。
				dir.mkdirs();
			}
			OutputStream os = new FileOutputStream(new File(dir,System.currentTimeMillis()+".jpg"));
			byte[] buf = new byte[1024];
			int len = 0;
			while((len = is.read(buf)) != -1) {
				os.write(buf,0,len);
			}
			os.close();
			is.close();
			client.close();
		}
	}
	
}

在这里插入图片描述


3.UDP编程

由于是无连接、不可靠,所以应用在视频会议、语音通话等。
使用的关键字:DatagramSocket发送和接受数据报包的套接字。每个在数据报套接字上发送或接受的包都是单独编址和路由的。为了接受广播包,应该将DatagramSocket绑定到通配符地址,在某些实现中,将DatagramSocket绑定到一个更加具体的地址时广播包也可以被接受。

DatagramSocket() 构造数据报套接字并将其绑定到本地主机上任何可用的端口。 —发送
DatagramSocket(int port) 创建数据报套接字并将其绑定到本地主机上的指定端口。 —接收
DatagramSocket(int port, InetAddress laddr) 创建数据报套接字,将其绑定到指定的本地地址。
void receive(DatagramPacket p) 从此套接字接收数据报包。
void send(DatagramPacket p) 从此套接字发送数据报包。 此方法在接收到数据报前一直阻塞

DatagramPacket 数据报包
DatagramPacket(byte[] buf, int length) 构造 DatagramPacket,用来接收长度为 length 的数据包。
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。

     byte[] getData() 返回数据缓冲区。 
     int getLength() 返回将要发送或接收到的数据的长度。 
     int getPort() 返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。 
     InetAddress getAddress() 返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。 
       		
InetAddress  此类表示互联网协议 (IP) 地址。IP 地址是 IP 使用的 32 位或 128 位无符号数字
	static InetAddress getByName(String host)  在给定主机名的情况下确定主机的 IP 地址。
	String getHostName()  获取此 IP 地址的主机名。 

练习:udp编程

UDP练习:“双人对话”
package Practice1.ddd;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

public class UDPClient {
	public static void main(String[] args){
		new Thread(new ReceiveTest()).start();
		DatagramSocket ds;
		try {
			ds = new DatagramSocket();//创建DatagramSocket对象。
			System.out.println("我们可以聊天了!");
			Scanner input = new Scanner(System.in);
			while(true) {
				String str = input.next();
				if("拜拜".equals(str)){
					break;//为了关闭资源。
				}
				byte[] buf = str.getBytes();//将字符串转换为字节码文件
				DatagramPacket dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("127.0.0.1"),9999);
				ds.send(dp);//发送数据。
				System.out.println(" send succeed");
			}
			ds.close();//关闭资源。
			System.out.println("下线");
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
class ReceiveTest implements Runnable{

	@Override
	public void run() {
		//创建对象
		DatagramSocket socket;
			try {
				socket = new DatagramSocket(7809);
				while(true) {
					byte[] buf = new byte[1024];
					//创建数据报包。
					DatagramPacket dp = new DatagramPacket(buf, buf.length);
					socket.receive(dp);//接受数据。
					byte[] data = dp.getData();
					int len = dp.getLength();
					System.out.println("收到来自"+dp.getAddress().getHostName()+":"+dp.getPort()+ "数据:   "+ new String(data,0,len));
				}
			} catch (SocketException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}
}

用户B:

package Practice1.ddd;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

public class UDPClientB {
	public static void main(String[] args){
		new Thread(new ReceiveTestB()).start();
		DatagramSocket ds;
		try {
			ds = new DatagramSocket();//创建DatagramSocket对象。
			System.out.println("我们可以聊天了!");
			Scanner input = new Scanner(System.in);
			while(true) {
				String str = input.next();
				if("拜拜".equals(str)){
					break;//为了关闭资源。
				}
				byte[] buf = str.getBytes();//将字符串转换为字节码文件
				DatagramPacket dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("127.0.0.1"),7809);
				ds.send(dp);//发送数据。
				System.out.println(" send succeed");
			}
			ds.close();//关闭资源。
			System.out.println("下线");
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
class ReceiveTestB implements Runnable{

	@Override
	public void run() {
		//创建对象
		DatagramSocket socket;
			try {
				socket = new DatagramSocket(9999);
				while(true) {
					byte[] buf = new byte[1024];
					//创建数据报包。
					DatagramPacket dp = new DatagramPacket(buf, buf.length);
					socket.receive(dp);//接受数据。
					byte[] data = dp.getData();
					int len = dp.getLength();
					System.out.println("收到来自"+dp.getAddress().getHostName()+":"+dp.getPort()+"数据:   "+ new String(data,0,len));
				}
			} catch (SocketException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心尘未泯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值