一.Java Socket通信相关理论知识
Java中的网络功能有四类:
(1)InetAddress:用于标识网络上的硬件资源--IP地址相关信息
无构造方法,通过提供的静态方法来获取实例。
(2)URL:统一资源定位符。通过URL可直接读取或写入网络上的数据
格式:“协议名称:资源名称”
URL对象的open stream()方法可得到指定的输入流,by输入流可以读取/访问网络上的数据
(3)Socket:使用TCP协议实现网络通信的Socket相关的类
(4)Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通信
常用端口号:
http 80
ftp 21
Telnet 23
1-1023是保留端口号,固定分配给一些服务。
基于TCP协议实现网络通信的类:
(1)客户端的Socket类
(2)服务器端的ServerSocket类
二.客户端和服务器的通信步骤
客户端
1.创建客户端Socket,指定服务器地址和端口
2.获取输出流,向服务器端发送信息
3.获取输入流,并读取服务器端的响应信息(可选)
4.关闭资源
服务器端
1.创建一个服务器端Socket--ServerSocket,指定绑定的端口并监听
2.调用accept()方法开始监听,等待客户端的连接
3.获取输入流,并读取客户端信息
4.获取输出流,响应客户端的请求(可选)
5.关闭资源
三.代码
客户端
package Communication;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) {
try {
//1.创建客户端Socket,指定服务器地址和端口
Socket socket=new Socket("localhost",8888);
//2.获取输出流,向服务器发送消息
/*
OutputStream os=socket.getOutputStream();
PrintWriter pw=new PrintWriter(os);//输出流包装为打印流
pw.write("用户名:admin;密码:123");
pw.flush();
socket.shutdownOutput();
*/
FileInputStream fis=null;
DataOutputStream dos=null;
File file=new File("D:\\新建文档.txt");
if(file.exists()) {
fis=new FileInputStream(file);
dos=new DataOutputStream(socket.getOutputStream());
//文件名和长度
dos.writeUTF(file.getName());
dos.flush();
dos.writeLong(file.length());
dos.flush();
}
System.out.println("===开始传输文件===");
byte[] bytes=new byte[1024];
int length=0;
long progress=0;
while( (length=fis.read(bytes,0,bytes.length) )!=-1) {
dos.write(bytes,0,length);
dos.flush();
progress+=length;
System.out.println("进度:"+progress/file.length());
}
System.out.println("===文件传输成功===");
//关闭资源
fis.close();
dos.close();
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务器端
package Communication;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
//1.创建按一个服务器端Socket,指定绑定的端口。并监听此端口
ServerSocket serverSocket=new ServerSocket(8888);
Socket socket=null;
int count=0;
System.out.println("***服务器即将启动,等待客户端的连接***");
while(true) {
//2.调用accept监听,等待客户端的连接
socket=serverSocket.accept();
//创建一个新线程
ServerThread serverThread=new ServerThread(socket);
//启动线程
serverThread.start();
count++;
System.out.println("客户端的数量:"+count);
InetAddress address=socket.getInetAddress();
System.out.println("当前客户端的IP:"+address.getHostAddress());
}
//serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务器线程处理类
package Communication;
/*
* 服务器线程处理类
*/
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerThread extends Thread {
//和本线程相关的Socket
Socket socket=null;
//构造函数
public ServerThread(Socket socket){
this.socket=socket;
}
//线程执行的操作,响应客户端的请求
public void run() {
DataInputStream dis=null;
FileOutputStream fos=null;
try {
dis=new DataInputStream(socket.getInputStream());
String fileName=dis.readUTF();
long fileLength=dis.readLong();
File directory=new File("D:\\get");
if(!directory.exists())
directory.mkdir();
File new_file=new File(directory.getAbsolutePath()+File.separatorChar+fileName);
fos=new FileOutputStream(new_file);
byte[] bytes=new byte[1024];
int length=0;
while( ( length=dis.read(bytes,0,bytes.length) )!=-1 ) {
fos.write(bytes, 0, length);
fos.flush();
}
System.out.println("===文件接收成功:文件名是"+fileName+"文件大小是:"+fileLength+"===");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {//关闭资源
dis.close();
fos.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}