最近学习了java网络编程,特在此记录,为方便日后查看,也为了广大小伙伴们有个参考(由易到难)。
最最重要的概念:
网络编程分为服务端和客户端。服务端就相当于我们平时说的服务器,有固定的IP地址,随时等待服务器连接并做出响应;而客户端相当于各种端系统,找到服务端进行连接获取服务(我们下面的程序也是这样,首先启动服务端等待连接,然后启动客户端连接服务端。如果先启动客户端再启动服务端则会报错)。
说到java的网络编程倒不如说是Java的I/O编程,因为整个过程中关于服务端和客户端的socket创建也就那么两三行代码,其余的都是操作字节流,字符流等。
思路:
服务端
(1) 创建服务器,指定端口ServerSocket(intport)
(2) 采用阻塞式接收客户端连接
(3) 当客户端连接时打印出“一个客户端建立连接字样”
(4) 建立字节输入流,接收客户端输入
(5) 建立字节输出流,将客户端输入的字节转换为大写后输出给客户端
(6) 清空缓存,但是并不关闭流,因为我们想循环接收用户输入,持续反应
客户端
(1) 创建客户端指定服务器+端口,此时就在连接
(2) 创建输入流,从键盘接收数据
(3) 创建字节输出流,将用户的输入通过socket传输给服务器
(4) 清空缓存
(5) 创建字节输入流接收服务器传回的数据,并打印出来
服务端代码:
package com.example.netsocket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
/**
* 1、//创建服务器,指定端口 ServerSocket(int port)
* 2、//接收客户端连接,阻塞式
* 3、发送数据+接受数据
* @author 竹轩听雨
*
*/
public class Server{
public static void main(String[] args) throws IOException {
//创建服务器,指定端口 ServerSocket(int port)
ServerSocket serverSocket = new ServerSocket(16066);
//接收客户端连接,阻塞式
Socket client = serverSocket.accept();
OutputStream out = client.getOutputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
DataInputStream dis = new DataInputStream(client.getInputStream());
DataOutputStream dos = new DataOutputStream(out);
String inputMsg = "";
String outputMsg = "";
System.out.println("一个客户端建立连接");
//发送数据
String msg = "欢迎连接";
while(true) {
//inputMsg = in.readLine();
inputMsg = dis.readUTF();
System.out.println(inputMsg);
dos.writeUTF("服务器-->" + inputMsg.toUpperCase());
dos.flush();
}
}
}
客户端代码:
package com.example.netsocket;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 1、创建客户端必须指定服务器+端口,此时就在连接
* 2、接收数据+发送数据
* @author 竹轩听雨
*
*/
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//创建客户端必须指定服务器+端口,此时就在连接
Socket client = new Socket("localhost",16066);
String outputMsg = "";
String inputMsg = "";
//控制台输入
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
DataInputStream dis = new DataInputStream(client.getInputStream());
while(true) {
//输出流
outputMsg =console.readLine();
if(outputMsg.equals("break"))
break;
dos.writeUTF(outputMsg);
dos.flush();
//输入流
inputMsg = dis.readUTF();
System.out.println(inputMsg);
}
//开始传输文件
//判断是否读到文件末尾
// while((len = fileReader.read(buf)) != -1) {
// out.write(buf,0,len);
// }
//输入流
// inputMsg = dis.readUTF();
// System.out.println(inputMsg);
//告诉服务器,文件已传输完毕
// dos.flush();
// //获取从服务器返回的信息
// inputMsg = dis.readUTF();
// System.out.println(inputMsg);
}
}
实验效果:
客户端连接后服务端显示“一个客户端建立连接字样”
在客户端输入数据后接收到服务端返回的大写数据
客户端接收到的输入
二、通过socket传输文本文件
思路:因为要传输中文字符,我们就不用循环逐个接收字节了,而是用更简单的字符流。
服务端
(1) 创建服务器,指定端口ServerSocket(intport)
(2) 采用阻塞式接收客户端连接
(3) 当客户端连接时打印出“一个客户端建立连接字样”
(4) 建立字符输入流,接收客户端输入
(5) 关闭输入流
(6) 将接收到的数据输出到控制台
(7) 建立字符输出流,将客户端输入的字符存储到E盘根目录下copy.txt文件(如果此文件不存在则会创建一个新的空白文件,如果存在则会覆盖其中的内容。当然也可以选择追加内容到里面)
(8) 关闭输出流
客户端
(1) 创建客户端指定服务器+端口,此时就在连接
(2) 创建字符输入流,从F盘根目录下test.txt文本文件中读取数据
(3) 关闭输入流
(4) 创建字符输出流,读取的字符通过socket传输给服务器
(5) 关闭输出流
(注:请在F盘根目录下放置一个test.txt文件)
服务端代码:
package com.example.filetranslation;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
public class FileServer {
public static void main(String[] args) throws IOException {
//创建服务器,指定端口 ServerSocket(int port)
ServerSocket serverSocket = new ServerSocket(16066);
//接收客户端连接,阻塞式
Socket client = serverSocket.accept();
InputStream in = client.getInputStream();
Reader reader = new InputStreamReader(in);
char[] data = new char[1024];
int len = 0;
File file = new File("E:" + File.separator + "copy.txt");
Writer writer = new FileWriter(file);
System.out.println("一个客户端建立连接");
len = reader.read(data);
reader.close();
System.out.println(new String(data,0,len));
if(!"".equals(data)) {
writer.write(data);
writer.close();
}
}
}
客户端代码
package com.example.filetranslation;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.Socket;
import java.net.UnknownHostException;
public class FileClient {
public static void main(String[] args) throws IOException, IOException {
//创建客户端必须指定服务器+端口,此时就在连接
Socket client = new Socket("localhost",16066);
File file = new File("F:" + File.separator + "test.txt");
int len = 0;
char[] data = new char[1024];
OutputStream out = client.getOutputStream();
Writer writer = new OutputStreamWriter(out);
if(file.exists()) {
Reader reader;
try {
reader = new FileReader(file);
len = reader.read(data);
reader.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println(new String(data,0,len));
}
if(!"".equals(data)) {
writer.write(data);
writer.close();
}
}
}
效果
F盘根目录下test.txt中的内容
控制台输出此内容且E盘根目录下出现test.txt文件
思路:(注意:须在F盘根目录下放置一个test.mp3文件)
服务端
(1) 创建服务器,指定端口ServerSocket(intport)
(2) 采用阻塞式接收客户端连接
(3) 当客户端连接时打印出“一个客户端建立连接字样”
(4) 建立字符输入流,接收客户端输入
(5) 从输入流中循环读取字节数据
(6) 建立输出流,将从输入流中读取的字节流输出到E盘根目录中
(7) 输入新缓冲区
(8)建立字符输出流,给客户端返回“文件上传成功”字样
(8) 关闭输出流,输出流,socket等
客户端
(1)创建客户端指定服务器+端口,此时就在连接
(2) 输入流,从F盘根目录下test.mp3中循环读取数据并将数据发送给服务端
(3) 告诉服务端文件已传输完毕
(4) 获取从服务端反馈的信息(文件上传成功或无信息)
(5) 将从服务端获得的反馈信息打印到控制台中
(6) 关闭输入流,输出流,socket等
服务端代码:
package com.example.kindsoffile;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
public class FileServer {
public static void main(String[] args) throws IOException {
//创建服务器,指定端口 ServerSocket(int port)
ServerSocket serverSocket = new ServerSocket(16066);
//接收客户端连接,阻塞式
Socket client = serverSocket.accept();
InputStream in = client.getInputStream();
OutputStream out = new FileOutputStream("E:" + File.separator + "test.mp3");
byte[] data = new byte[1024];
int len = 0;
while((len = in.read(data)) != -1) {
out.write(data,0,len);
out.flush();
}
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
bw.write("文件上传成功");
bw.flush();
serverSocket.close();
client.close();
out.close();
}
}
客户端代码:
package com.example.kindsoffile;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.Socket;
public class FileClient {
public static void main(String[] args) throws IOException, IOException {
//创建客户端必须指定服务器+端口,此时就在连接
Socket client = new Socket("localhost",16066);
OutputStream out = client.getOutputStream();
InputStream in = new FileInputStream("F:" + File.separator + "test.mp3");
int len = 0;
byte[] data = new byte[1024];
while((len = in.read(data)) != -1) {
out.write(data,0,len);
}
//告诉服务器文件已传输完毕
client.shutdownOutput();
//获取从服务端反馈的信息
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println(br.readLine());
//关闭资源
client.close();
in.close();
}
}
效果
客户端显示服务端传回的“文件上传成功字样”并且在E盘根目录找到test.mp3文件