14.Java中的网络编程【Java学习笔记Hatter】Java开发工程师
有效端口:0~65535,其中0~1024位系统使用或保留端口
IP地址段相同才可以通讯
127.0.0.1本地回环地址,本机没有配任何ip地址,即本机默认IP地址
1.OSI参考模型与TCP/IP模型
传送方各层加上自己的特征封装后一层一层往下加,接收方接收到后 再层层拆包往上传
2.UDP
将数据以及源和目的封装成数据包,不需建立连接
每个数据包的大小限制在64k内
因无连接,是不可靠协议
不需要建立连接,速度快
3.TCP
建立连接,形成传输数据的通道
在连接中 进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接, 效率会稍低
4.Socket
就是为网络服务提供的一种机制
通信两端都要有Socket
网络通信就是Socket之间的通信
数据在两个Socket间通过IO进行传输
例:定义一个应用程序,用于接收udp协议传输的数据并处理
再定义一个应用程序,用于接收udp协议传输的数据并处理
思路:
①首先建立udp的socket服务(建立端点),监听一个端口,其实就是给这个接收网络应用程序定义数字标识。
②提供数据,并将数据封装到数据包中
③通过socket服务的发送功能,将数据包发出去
④关闭资源。
⑤先定义一个socket服务。
⑥定义一个数据包,用来存储接收到的字节数据。
⑦然后通过socket服务的receive方法将接收到的这些字节数据存到已经定义好的数据包中封装起来。
⑧接着通过数据包对象的特有功能,将这些不同的数据取出。打印在控制台上。
⑨完成后关闭资源。
Tcp分客户端和服务端
客户端对应的对象是Socket
服务端对应的对象是ServerSocket
客户端:
思路:
通过查阅socket对象,在该对象建立时候,就可以去连接指定主机。
因为tcp是面向连接的,所以在建立socket时,就需要有服务端的存在,并且要连接成功。
形成通路后,在该通道进行数据的传输。
服务端:
建立服务端的socket服务。ServerSocket();并且监听一个端口。
获取连接过来的客户端对象,通过ServerSocket的accept方法,所以这个方法是阻塞式的。
客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据,并打印在控制台
关闭服务器(可选操作)
例:
UDP聊天程序
客户端:
public class UdpSendDemo2 {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
BufferedReader br =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line = br.readLine()) != null) {
if ("over".equals(line))
break;
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName("192.168.2.115"), 10001);
ds.send(dp);
}
ds.close();
}
}
服务端:
public class UdpReceiveDemo2 {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(10001);
while (true) {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);//阻塞式方法
String ip = dp.getAddress().getHostAddress();
String receive_data = new String(dp.getData(), 0, dp.getLength());
int port = dp.getPort();
System.out.println(ip + "::" + receive_data + "::" + port);
}
}
}
例:
TCP传输
客户端:
public class TcpClientDemo2 {
public static void main(String[] args) throws IOException {
Socket s=new Socket("192.153.23.155",10006);
OutputStream out=s.getOutputStream();
out.write("client come".getBytes());
InputStream in=s.getInputStream();
byte[]buf=new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
s.close();
}
}
服务端:
public class TcpServerDemo2 {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10006);
Socket s=ss.accept();
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"....lianjie");
InputStream in=s.getInputStream();
byte[]buf=new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
OutputStream out=s.getOutputStream();
out.write("server receive ".getBytes());
s.close();
}
}
例:建立一个文本转换器
客户端给服务端发送文本,服务端会将文本转成大写再返回给客户端,而且客户端可以不断的进行文本转换。当客户端输入over时候,转换结束
客户端:
源:键盘录入
目的:网络设备,网络输出流
操作的是文本数据,可以选择字符流
服务端:
源:socket读取流
目的:socket输出流
都是文本,装饰
客户端:
public class TransClient {
public static void main(String[] args) throws UnknownHostException, IOException {
//1.创建socket客户端对象。
Socket s = new Socket("192.168.1.100",10010);
//2.获取键盘录入。
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
//3.socket输出流。
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
//4.socket输入流,读取服务端返回的大写数据
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null){
if("over".equals(line))
break;
out.println(line);
//读取服务端发回的一行大写数。
String upperStr = bufIn.readLine();
System.out.println(upperStr);
}
s.close();
}
}
服务端:
public class TransServer {
public static void main(String[] args) throws IOException {
1.创建服务端的socket并监听指定端口
ServerSocket ss = new ServerSocket(10010);
//2.获取socket对象。
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"......connected");
//3.获取socket读取流,并装饰。
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
//4.获取socket的输出流,并装饰。
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufIn.readLine())!=null){
System.out.println(line);
out.println(line.toUpperCase());
}
s.close();
ss.close();
}
}
例:
TCP复制文件
客户端:
public class UploadClient {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("上传客户端。。。。。。");
File file = new File("c://IpDemo.java");
System.out.println(file.exists());
//1.创建Socket服务并与指定的IP地址,端口号连接
Socket s = new Socket("192.164.23.125",10013);
//2.定义读取键盘数据的流对象
BufferedReader bufr =
new BufferedReader(new FileReader(file));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
while((line=bufr.readLine())!=null){
out.println(line);
}
//告诉服务端,客户端写完了。
s.shutdownOutput();
//3.定义一个socket读取流,读取服务端的返回的大写信息
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = bufIn.readLine();
System.out.println(str);
bufr.close();
s.close();
}
}
服务端:
public class UploadServer {
public static void main(String[] args) throws IOException {
System.out.println("上传服务端......");
ServerSocket ss = new ServerSocket(10013);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress()+".....connected");
//3读取socket读取流中的数据
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
//4目的,socket输出流,将大写数据写入到socket输出流,并发送给客户端
BufferedWriter bufw = new BufferedWriter(new FileWriter("e://server.txt"));
String line = null;
while((line=bufIn.readLine())!=null){
bufw.write(line);
bufw.newLine();
bufw.flush();
}
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.println("上传成功");
bufw.close();
s.close();
ss.close();
}
}


1914篇文章