网络编程
public class Demo01TCP_Client {
/*socket:网络编程: 在网络之间 实现不同计算机之间的数据传输
*
*ip:互联网上每台计算机的唯一标识
* ---ipv4:4个1byte组成: 192.168.2.110
* ---ipv6:8个2byte组成 16进制表示: cccc.cccc.8889.af89.1111.121a.1111.a001
*域名:给ip对应的方便记忆的字符串
*本地ip:127.0.0.1 localhost
*port:电脑上安装的每个软件都会分配一个唯一的编号:0-65535
* 10000以下的被分配给操作系统
*网络传输协议: 计算机网络中实现通信必须有一些约定即通信协议,对速率、传输代码、代码结构、传 输控制步骤、出错控制等制定标准。
*
*TCP: transimission control protocol: (打固定电话)
* 可控的 端对端的 字节流传输协议
* 主要类:Socket+ServerSocket
*
*
*UDP: user datagram protocol :(发报机)
* 不可靠的 无需连接的 报文流传输协议
* 主要类:DatagramSocket+DatagramPackage
*
*TCP:
* 服务器:部署项目的主机
* 客户: 访问服务器资源的互联网用户
*
* 服务器端:
* 1 创建一个serversocket并指定一个端口------架了一个固定电话 还买了一个电话号
* 2 等待客户端的连接----等待别人给我打电话
* 3 获取socket的输入流和输出流 进行数据传输 ----接电话 进行停和说
* 4 关闭服务serversocket----挂断电话
* 客户端:
* 1 创建一个socket指定服务器端的ip和端口---- 给服务器之间拉一个电话线
* socket---套接字---传输通道
* 2 获取socket的输入流和输出流 进行数据传输 ----拨通电话 进行听和说
* 3 关闭socket----剪断电话线
* */
TCP
服务器:部署项目的主机
客户:访问服务器资源的互联网用户
tcp 步骤:
服务器端
1.创建一个ServerSocket 并指定一个端口——架了一个固定电话 还买了一个电话号
2.等待客户端的连接–等待别人打电话
3.获取socket 的 输入、输出流,进行数据传输—接电话 进行听和说
4.关闭服务ServerSocket —挂断电话
代码:
ServerSocket server=new ServerSocket(10086);//指定要开启那个端口 来接受客户端的信息
// * 2 等待客户端的连接----等待别人给我打电话
System.out.println("服务器端等待连接---");
Socket socket=server.accept();//等待并获取客户端连接--阻塞方法
// * 3 获取socket的输入流和输出流 进行数据传输 ----接电话 进行停和说
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
out.write("hello 谁啊?".getBytes());//服务器先说话:
byte[] arr=new byte[1024];//接受客户端回应
int n=in.read(arr);
System.out.println("客户端的回答是:"+new String(arr,0,n));
out.write("不认识 打错了!".getBytes());
// * 4 关闭服务serversocket----挂断电话
server.close();
}
客户端
1.创建一个socket指定服务器的端口和ip----给服务器之间拉一个电话线
socket:–套接字–传输通道
2.获取socket的输入流和输出流 进行数据传输 -----拨通电话 进行听和说
3.关闭socket ----剪断电话线
代码:
// * 1 创建一个socket指定服务器端的ip和端口---- 给服务器之间拉一个电话线
// * socket---套接字---传输通道
Socket socket=new Socket("127.0.0.1", 10086);
// * 2 获取socket的输入流和输出流 进行数据传输 ----拨通电话 进行听和说
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
byte[] arr=new byte[1024];
int n=in.read(arr);
System.out.println("服务器端说:"+new String(arr,0,n));
out.write("我是苗天宝,找你借点钱!".getBytes());
n=in.read(arr);
System.out.println("服务器端说:"+new String(arr,0,n));
// * 3 关闭socket----剪断电话线
socket.close();
}
让服务器端对客户端发送的数据进行转换 删除数组 大写转小写 小写转换为大写
Client
//1 创建socket:指定服务器端的ip和服务器端开启的端口
Socket socket=new Socket("127.0.0.1", 10086);
String localIp=socket.getLocalAddress().getHostName();
int localPort=socket.getLocalPort();
String ip=socket.getInetAddress().getHostName();
int port=socket.getPort();
System.out.println("客户端::::localIp="+localIp+":::localPort="+localPort);
System.out.println("客户端::::ip="+ip+":::port="+port);
//2 获取输入流和输出流
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
//3接受和发送信息
//获取键盘输入的信息
BufferedReader bin=new BufferedReader(new InputStreamReader(System.in));
while(true) {
System.out.println("请输入一行数据:如果要结束 请输入886");
String line=bin.readLine();
out.write(line.getBytes());//通过socket的输出流把读取的信息发出去
byte[] arr=new byte[1024];
int n=in.read(arr);//接受服务器端的信息
String message=new String(arr, 0,n);
System.out.println("客户端接受到的信息是:"+message);
if(line.contains("886")) {
break;
}
}
//4关闭socket
socket.close();
}
server
//1 创建服务
ServerSocket server=new ServerSocket(10086);//开启的端口是10086 此端口可以给客户端进行数据传输
//2 等待连接 获取socket:传输通道
System.out.println("服务器端开启端口10086开始服务::::");
Socket socket=server.accept();//阻塞方法:等待客户端连接
String localIp=socket.getLocalAddress().getHostName();
int localPort=socket.getLocalPort();
String ip=socket.getInetAddress().getHostName();
int port=socket.getPort();
System.out.println("服务器端::::localIp="+localIp+":::localPort="+localPort);
System.out.println("服务器端::::ip="+ip+":::port="+port);
//3 从传输通道中获取输入流和输出流
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
//4 通过输入流和输出流发送信息
while(true) {
byte[] arr=new byte[1024];
int n=in.read(arr);
String message=new String(arr, 0, n);
System.out.println("接收到客户端信息:"+message);
String messageNew=change(message);//字符串转换
out.write(messageNew.getBytes());
if(message.contains("886")) {
break;
}
}
//5关闭服务
server.close();
}
private static String change(String s) {
StringBuffer stb=new StringBuffer(s);
for (int i = 0; i < stb.length(); i++) {
char c=stb.charAt(i);
if(Character.isUpperCase(c)) {
stb.setCharAt(i, Character.toLowerCase(c));
}else if(Character.isLowerCase(c)) {
stb.setCharAt(i, Character.toUpperCase(c));
}else if(Character.isDigit(c)) {
stb.deleteCharAt(i);
i--;
}
}
return stb.toString();
}
通过tcp实现文件上传
client:
/*1 创建一个流与源文件关联
*2 创建socket与服务器端连接
*3 通过socket的输出流把文件的名字传递给服务器端
*4 通过socket的输出流把文件中的信息传递给服务器端
*5读到末尾 就上传完毕 关闭socket
* */
//创建流与源文件关联
File file=new File("src\\test\\1.jpg");
FileInputStream fin=new FileInputStream(file);
//创建socket指定服务器的ip和端口
Socket socket=new Socket("localhost", 10010);
//获取输出流
OutputStream out=socket.getOutputStream();
//把文件民写出去
out.write(file.getName().getBytes());
//一边读文件 一边通过sockct发送信息给服务器
byte[] arr=new byte[1024];
int n;
while((n=fin.read(arr))!=-1) {
out.write(arr, 0, n);
}
socket.shutdownOutput();//关闭输出流
//获取输入流来获取服务器端的反馈
InputStream in=socket.getInputStream();
n=in.read(arr);
System.out.println("接收到服务器端的信息是:"+new String(arr, 0,n));
//关闭socket
socket.close();
server:
//创建服务
ServerSocket server=new ServerSocket(10010);
//获取连接
Socket socket=server.accept();
//获取输入流
InputStream sin=socket.getInputStream();
//获取文件名字
byte[] arr=new byte[1024];
int n=sin.read(arr);
String fileName=new String(arr, 0,n);
//1 创建文件输出流与目的文件关联
FileOutputStream fout=new FileOutputStream("d:\\"+fileName);
//一边从socket中读信息 一边把信息写到目的文件中
while((n=sin.read(arr))!=-1) {
fout.write(arr, 0, n);
}
//给客户端发送反馈信息
OutputStream sout=socket.getOutputStream();
sout.write(("接受文件"+fileName+"成功!").getBytes());
//关闭服务
server.close();
}
聊天(使用线程):
client
public class Demo04Chat_Client {
public static void main(String[] args)throws Exception {
//获取键盘的信息 发给服务器端
BufferedReader bin=new BufferedReader(new InputStreamReader(System.in));
//创建socket 指定服务器端的ip和端口
Socket socket=new Socket("192.168.217.32", 10086);
//获取socket的输出流和输出流
InputStream in=socket.getInputStream();
OutputStream out=socket.getOutputStream();
//为了实现收发同步 需要创建两个线程 分别来控制输入流和输出流
new InThreadClient(in).start();
new OutThreadClient(out,bin).start();
}
}
class InThreadClient extends Thread{
InputStream in;
InThreadClient(InputStream in) {this.in=in;}
public void run() {
try {
byte[] arr=new byte[1024];
int n;
while((n=in.read(arr))!=-1) {
System.out.println(new String(arr, 0, n));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
class OutThreadClient extends Thread{
OutputStream out;
BufferedReader bin;
OutThreadClient(OutputStream out,BufferedReader bin) {this.out=out;this.bin=bin;}
public void run() {
try {
String line;
while((line=bin.readLine())!=null) {
out.write(line.getBytes());
if(line.contains("886")) {
break;
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
server
public class Demo04Chat_Server {
// 创建s
public static void main(String[] args) throws Exception{
// 1 创建serversocket
ServerSocket ss=new ServerSocket(10086);
// 2 获取socket
HashSet<OutputStream> set=new HashSet<>();
while(true) {
Socket socket=ss.accept();
set.add(socket.getOutputStream());
new InOutThread(socket,set).start();
}
}
}
class InOutThread extends Thread{
Socket socket;
HashSet<OutputStream> set;
InOutThread(Socket socket,HashSet<OutputStream> set){
this.socket=socket;
this.set=set;
}
public void run() {
String ip_port=socket.getInetAddress().getHostName()+"_"+socket.getPort()+"说:";
try {
InputStream in=socket.getInputStream();
byte[] arr=new byte[1024];
int n;
while((n=in.read(arr))!=-1) {
String message=new String(arr, 0, n);
for (OutputStream out : set) {
out.write((ip_port+message).getBytes());
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
文件复制
//服务器端
ServerSocket ss=new ServerScoket(10086);//创建服务
Socket socket=ss.accept();//等待连接
InputStream in=socket.getInputStream();
byte[] arr=new byte[1024]; int n;
n=in.read(arr);//先获取文件名字
String fileName=new String(arr,0,n);
//创建输出流与目的文件关联
BufferedOutputStream bout=new BufferedOutputStream(new FileOutputStream(fileName));
//一边从socket中读取信息 一般把信息写到目的文件中
while((n=in.read(arr))!=-1){
bout.write(arr,0.n);
bout.flush();
}
//给客户端反馈
OutputStream out=socket.getOutputStream();
out.write(("接受"+fileName+"成功").getBytes());
//关闭服务
bout.close();
ss.close();
//客户端:
File file=new File("d:\\1.jpg");
Socket socket=new Socket("127.0.0.1",10086);
OutputStream out=socket.getOutputStream();
out.write(file.getName().getBytes());//先发送文件名字
//创建输入流与源文件关联
BufferedInputStream bin=new BufferedInputStream(new FileInputStream(file));
//边读边发
byte[] arr=new byte[1024]; int n;
while((n=bin.read(arr))!=-1){
out.write(arr,0,n);
}
socket.shutDownOutputStream();//关闭socket的输出流
//获取服务器端的反馈
InputStream in=socket.getInputStream();
n=in.read(arr);
System.out.println("服务器端的反馈:"+new String(arr,0,n));
socket.close();
UDP
发送方
/*
* UDP:user datagram protocol
* 不可靠的 无需连接的 报文流传输协议
* 发送方:
*
*
* */
public static void main(String[] args) throws Exception{
//1:创建udp的socket: 指定开启的端口
DatagramSocket socket=new DatagramSocket(10086);
//2:创建一个datagrampackage封装要发送的信息
byte[] arr="你好吗udp".getBytes();
DatagramPacket sendPacket=new DatagramPacket(arr, 0, arr.length, InetAddress.getByName("127.0.0.1"), 10010);
//参数解释:arr:要发送的信息对应的字节数组, 0:要发送的字节从哪里开始发, arr.length:要发的字节总数,
// InetAddress.getByName("127.0.0.1"):接受方的ip, 10010:接受方的端口
//DatagramPacket有6个构造方法:
//构造方法中 需要ip和端口的用于发送
//构造方法中 不需要ip和端口的用于接受
//3 通过socket把数据报包发出去
socket.send(sendPacket);
//4 关闭socket
socket.close();
}
接收方
/*
* UDP:user datagram protocol
* 不可靠的 无需连接的 报文流传输协议
*接收方
*
*
* */
public static void main(String[] args) throws Exception{
//接收方:
//1 创建一个udp的socket:并指定要开启的端口
DatagramSocket socket=new DatagramSocket(10010);
//2 创建一个空的datagarampacket来接受信息
byte[] arr=new byte[1024];//定义一个字节数组 装信息
DatagramPacket receivePacket=new DatagramPacket(arr, arr.length);
//3接受信息
socket.receive(receivePacket);//使用空的DatagramPacket来接受信息:信息存放到arr中
//从数组中解析信息
//receivePacket.getLength();//获取接受的有效信息字节数
int length=receivePacket.getLength();
System.out.println("10010接受到的信息是:"+new String(arr, 0, length));
System.out.println("getAddress:"+receivePacket.getAddress().getHostName());
System.out.println("getPort:"+receivePacket.getPort());
//4 关闭socket
socket.close();
聊天(使用线程)
public class Demo07UDP {
public static void main(String[] args)throws Exception {
startUDP(10010,10086,"192.168.217.255");
}
public static void startUDP(int myPort,int port,String ip)throws Exception {
//创建一个socket
DatagramSocket socket=new DatagramSocket(myPort);
System.out.println(myPort+"开始聊天。。。。");
//一个线程只管发送
new SendThread(socket, port, ip).start();;
//一个线程只管接受
new ReceiveThread(socket).start();;
}
}
class SendThread extends Thread{
DatagramSocket socket;
int port;String ip;
SendThread(DatagramSocket socket,int port,String ip){this.socket=socket;this.port=port;this.ip=ip;}
public void run() {
//获取键盘输入流
BufferedReader bin=new BufferedReader(new InputStreamReader(System.in));
String line;
try {
while(true) {
line=bin.readLine();
byte[] arr=line.getBytes();
DatagramPacket sendPacket=new DatagramPacket(arr, arr.length, InetAddress.getByName(ip), port);
socket.send(sendPacket);
if(line.contains("886")) {
break;
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
socket.close();
}
}
}
class ReceiveThread extends Thread{
DatagramSocket socket;
ReceiveThread(DatagramSocket socket){this.socket=socket;}
public void run() {
byte[] arr=new byte[1024];
try {
while(true) {
DatagramPacket receivePacket=new DatagramPacket(arr, 0, arr.length);
socket.receive(receivePacket);
//数据解析
String message=new String(arr,0,receivePacket.getLength());
String ip_port=receivePacket.getAddress().getHostName()+"_"+receivePacket.getPort();
System.out.println(socket.getLocalPort()+"接收到"+ip_port+"的信息:"+message);
if(message.contains("886")) {
break;
}
}
} catch (SocketException e) {
System.out.println(socket.getLocalPort()+"结束聊天!!!");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
//1 互发信息
public class Demo06UDP_2 {
//先收 后发
public static void main(String[] args) throws Exception{
BufferedReader bin=new BufferedReader(new InputStreamReader(System.in));
//1 创建datagramsocket指定要开启的端口
DatagramSocket socket=new DatagramSocket(10086);
//2 创建一个datagrampacket用于发送信息
while(true) {
//创建一个空的datagrampakcet用于接受信息
byte[] arr=new byte[1024];
DatagramPacket receivePacket=new DatagramPacket(arr, arr.length);
socket.receive(receivePacket);
//解析信息
String message=new String(arr, 0,receivePacket.getLength());
System.out.println("10010接受到10086的信息是:"+message);
String line=bin.readLine();//从键盘读取一行信息
arr=line.getBytes();
//把读取的信息通过udp发送出去
DatagramPacket sendPacket=new DatagramPacket(arr, arr.length, InetAddress.getByName("localhost"), 10010);
socket.send(sendPacket);
if(line.contains("886")||message.contains("886")) {
break;
}
}
//关闭socket
socket.close();
}
}
public class Demo06UDP_1 {
public static void main(String[] args) throws Exception{
BufferedReader bin=new BufferedReader(new InputStreamReader(System.in));
//1 创建datagramsocket指定要开启的端口
DatagramSocket socket=new DatagramSocket(10010);
//2 创建一个datagrampacket用于发送信息
while(true) {
String line=bin.readLine();//从键盘读取一行信息
byte[] arr=line.getBytes();
//把读取的信息通过udp发送出去
DatagramPacket sendPacket=new DatagramPacket(arr, arr.length, InetAddress.getByName("localhost"), 10086);
socket.send(sendPacket);
//创建一个空的datagrampakcet用于接受信息
arr=new byte[1024];
DatagramPacket receivePacket=new DatagramPacket(arr, arr.length);
socket.receive(receivePacket);
//解析信息
String message=new String(arr, 0,receivePacket.getLength());
System.out.println("10010接受到10086的信息是:"+message);
if(line.contains("886")||message.contains("886")) {
break;
}
}
//关闭socket
socket.close();
}
}
本文深入探讨了TCP和UDP两种网络传输协议,详细解析了它们的工作原理和适用场景。通过实例展示了TCP服务器和客户端的交互过程,包括创建Socket、数据传输和关闭连接。同时,介绍了UDP的不可靠、无需连接特性,以及发送和接收数据报包的实现。文章还涵盖了基于TCP和UDP的文件传输、聊天应用和多线程编程的应用案例。
1427

被折叠的 条评论
为什么被折叠?



