什么是计算机网络编程。
首先我们应当TCP/IP 协议泛指互联网协议,其中最重要的两个协议是 TCP协议 和 IP协议 。只有使用 TCP/IP协议 的计算机才能够联入互联网。
IP协议:一种分组交换传输协议
TCP协议:一种面向连接,可靠传输的协议;
UDP协议:一种无连接,不可靠传输的协议。
Java网络编程
在 java.net 包中提供了两种常见的网络协议的支持:
- TCP:TCP 是传输控制协议的缩写,它保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP。
- UDP:UDP 是用户数据报协议的缩写,一个无连接的协议。提供了应用程序之间要发送的数据的数据包。
Socket套接字网络编程:
那么什么是套接字呢?
一个 Socket 套接字就是由IP地址和端口号(范围0~65535)组成,可以把 Socket 简单理解为 IP 地址加端口号。端口号总是由操作系统分配,它是一个 0 ~ 65535 之间的数字,其中,小于 1024 的端口属于 特权端口,需要管理员权限,大于 1024 的端口可以由任意用户的应用程序打开。
套接字使用TCP提供了两台计算机之间的通信机制。
1、客户端Client程序创建一个套接字,并尝试连接服务器的套接字。
2、当连接建立时,服务器(Server)会创建一个 Socket 对象。
3、客户端和服务器现在可以通过对 Socket 对象的写入和读取来进行通信。
java.net.Socket 类
代表一个套接字,并且 java.net.ServerSocket 类
为服务器程序提供了一种来监听客户端,并与他们建立连接的机制。
以下是基于TCP/IP协议的客户端(Client)示意代码
public class Demo01 {
public static void main(String[] args) {
//客户端
try(Socket client = new Socket("192.168.254.166",8848);//连接服务器的ip地址以及端口号
OutputStream ops = client.getOutputStream(); //客户端的一个输出流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\tupian\\hyz.png"));) {
byte[] buff = new byte[1024];
int len = -1;
while((len=bis.read(buff))!=-1) {
ops.write(buff,0,len);
}//通过输出流OPS的write方法写入D:\\tupian\\hyz.png的图片
client.shutdownOutput();//关闭输出流
try(BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));) {
String reply = reader.readLine();
System.out.println("服务器反馈"+reply);//输入流 获取服务器端的反馈
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
以下是基于TCP/IP协议的服务器端(Server)示意代码
public class Demo02Server {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8848);//监听的端口号
//死循环,确保服务器开启
while (true) {
Socket client = server.accept();//.accept() 表示每当有新的客户端连接进来后,就返回一个 Socket 实例,这个 Socket 实例就是用来和刚连接的客
//户端进行通信的。
InetAddress clientadd = client.getInetAddress();//获取客户端ip地址
System.out.println("客户端"+clientadd.getHostAddress()+"开始连接.................");
String imageName = clientadd.getHostAddress().replaceAll("\\.", "-")+".jpg";//客户端收到的图片名字
try (InputStream in = client.getInputStream();
BufferedInputStream bis = new BufferedInputStream(in);//读取client传的图片
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\tupian11\\"+imageName));){
byte[] buff = new byte[1024];
int len = -1;
while((len=bis.read(buff))!=-1) {
bos.write(buff,0,len);
}//写入到本机的磁盘
System.out.println("图片读取完毕");
try(BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));) {
writer.write("upload Success");
writer.newLine();
}//将读取成功upload Success输出到Client
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Java UDP编程
首先我们应当明确,在UDP编程中发送端与接收端是两个独立的运行程序。UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。
类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。
UDP数据报通过数据报套接字 DatagramSocket 发送和接收。
服务器端用 DatagramSocket(port) 监听端口;
客户端使用 DatagramSocket.connect() 指定远程地址和端口;
双方通过 receive() 和 send() 读写数据;
DatagramSocket 没有 IO 流接口,数据被直接写入 byte[] 缓冲区。
以下是基于UDP协议的客户端(Client)示意代码
package com.my.hyz3;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Scanner;
//客户端Client
public class Demo01 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(true){//死循环确保联系
String word = input.nextLine();
if(word.equals("gg")) {
break;//当打 gg使循环中止
}
try (DatagramSocket clientSocket = new DatagramSocket()) {
clientSocket.setSoTimeout(20000); //timeout时间
clientSocket.connect(new InetSocketAddress("192.168.254.185",8849));//获取与服务器端连接
//String word = input.nextLine();
byte[] wordBuff = word.getBytes(); //获取英文单词的字节数组
DatagramPacket packet = new DatagramPacket(wordBuff, wordBuff.length);
clientSocket.send(packet);//发送读取到的word
//读取
byte[] resultByte = new byte[1024];
DatagramPacket resultPacket = new DatagramPacket(resultByte, resultByte.length);
clientSocket.receive(resultPacket);//接收读取到的结果
String result = new String(resultPacket.getData(),resultPacket.getOffset(),resultPacket.getLength());
System.out.println("服务器告诉你:"+result);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
以下是基于UDP协议的服务器端(Server)示意代码
public class Demo01Server {
public static void main(String[] args) {
Map<String, String> wordMap = new HashMap<String, String>();
wordMap.put("one", "一");
wordMap.put("two", "二");
wordMap.put("three", "三");
wordMap.put("four", "4");
wordMap.put("five", "5");
wordMap.put("six", "6");
try (DatagramSocket serverSocket = new DatagramSocket(8849)) {
while(true) {
//准备空的包
byte[] buff = new byte[1024];
DatagramPacket packet = new DatagramPacket(buff, buff.length);
//读取Client发送的包
serverSocket.receive(packet);
//获取包中的“数据” (字节数组)中
//获取包中的“数据”读取位置(int类型)
//获取包中的长度
String word = new String(packet.getData(),packet.getOffset(),packet.getLength());
System.out.println("【服务器】:获取来自Client的Word为"+word);
String chinese = wordMap.get(word);
if(chinese==null) {
chinese="你在干嘛?在干嘛?白给吗";
}
//客户端发
byte[] resultbyte = chinese.getBytes();
packet.setData(resultbyte);
serverSocket.send(packet);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}