实现功能:
1、基于上一版本,这次实现了传输文件,要注意所有的读入写入,输入输出的接口以及写法要一致,否则会乱码
注:大家参考就好了,不要照搬啊!!!
代码展示:
客户端:
import java.io.*;
import java.net.*;
public class TalkClient {
public static void main(String args[]) {
try{
//向本机的4700端口发出客户请求
Socket socket=new Socket("127.0.0.1",4700);
//System.out.println(socket);//输出本客户端的编号,方便观察,可删除
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));//键盘输入流
DataOutputStream os=new DataOutputStream(socket.getOutputStream());//消息,文件输出流
DataInputStream is=new DataInputStream(socket.getInputStream());//消息,文件输入流
String readline;
System.out.println("样例:1 hello 或者 1 hello.txt");
while(true){
if(sin.ready())//DataOutputStream特有的方法,在不读取的情况下,查看缓冲区是否有可读取的内容
{//如果键盘有输入,即先发消息
readline=sin.readLine();
os.writeUTF(readline);
os.flush();//刷新输出流,使Server马上收到该字符串
String[] talk=readline.split(" ");
String[] wj=talk[1].split("\\.");//分割字符串,判断是否要发送文件
if(wj.length>1)//如果要发送文件
{
File f = new File(talk[1]);
FileInputStream fis = new FileInputStream(f);//读文件对象,该文件就在根目录下
int m,len;
long l=f.length(); //获取文件长度,单位kb
if((l%512)!=0) len = m = 512;
else len = m = 511;//防止文件正好是512字节的倍数
byte buffer[] = new byte[m];//读取输入流 ,一次读取512字节
//while ((len=fis.read(buffer,0,m))!=-1) {
while (len>=m) {//这while不能用上面注释的那个,read会阻塞
len=fis.read(buffer,0,m);
os.write(buffer,0,len);
os.flush();
}
fis.close();
System.out.println("文件读取发送成功!");
}
else
if(talk[1].equals("bye"))//若从标准输入读入的字符串为 "bye"则停止循环
{
break;
}
}
if(is.available()>0)//如果先收消息,也是先available()查看输入流的长度(未读取的情况下)
{
String get=is.readUTF();
System.out.println(get);
String[] wj1=get.split(" ");
String[] wj2=wj1[2].split("\\.");//判断是否要收文件
if(wj2.length>1)
{
String name = "E:\\"+wj1[2];//文件名为原文件名,自己指定目录
File file = new File(name);
if(!file.exists()){
file.createNewFile();
System.out.println("文件已新建!");
}
FileOutputStream fos = new FileOutputStream(name);//文件写入对象
System.out.println(name);
int n=512,len=512;
byte[] data = new byte[n];//一次读取字节,一般不会太大
while(len>=n)//判断是否有可以读取的数据
{
len=is.read(data,0,n);
//一定要用DataInputStream,他有方法可以判断缓冲区是否有内容,这样就不会在没有内容时用read()阻塞了
fos.write(data,0,len);
fos.flush();
//System.out.println(len);
}
System.out.println("文件已上传成功!");
fos.close();
}
}
} //继续循环
os.close(); //关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
System.out.println("您已退出系统!");
}catch(Exception e) {
System.out.println("Error"+e); //出错,则打印出错信息
}
}
}
服务端:
import java.io.*;
import java.net.*;
public class MultiTalkServer{
public static Socket[] socket=new Socket[10];//建立Socket数组,这里简单编写,用静态数组
static int clientnum=0; //静态成员变量,记录当前客户的个数
public static void main(String args[]) throws IOException {
ServerSocket serverSocket=null;
boolean listening=true;
try{
//创建一个ServerSocket在端口4700监听客户请求
serverSocket=new ServerSocket(4700);
}catch(IOException e) {
System.out.println("Could not listen on port:4700.");
//出错,打印出错信息
System.exit(-1); //退出
}
System.out.println("开始连接客户端......");
while(listening){ //循环监听
//监听到客户请求,根据得到的Socket对象和客户计数创建服务线程,并启动之
socket[clientnum]=serverSocket.accept();//保存监听到的客户端,这步很重要
new ServerThread(socket[clientnum],clientnum).start();
clientnum++; //增加客户计数
}
serverSocket.close(); //关闭ServerSocket
}
}
线程:
import java.io.*;
import java.net.*;
public class ServerThread extends Thread{
Socket lssocket=null;
Socket socket=null; //保存与本线程相关的Socket对象
int p;//用来记录这是第几个客户端
static int clientnum; //保存本进程的客户计数
public ServerThread(Socket socket,int num) { //构造函数
this.socket=socket; //初始化socket变量
clientnum=num+1; //初始化clientnum变量
p=num;//这里是从0开始编号客户端
}
public void run() { //线程主体
try{
String line;
//消息,文件输入流
DataInputStream is=new DataInputStream(socket.getInputStream());
while(true){
if(is.available()>0)
{
line=is.readUTF();//读取字符串,格式example: 1 aaa
String[] talk=line.split(" ");//以空格为分隔符分割字符串
int number = Integer.parseInt(talk[0]);//这是要收消息的客户端的编号
lssocket=MultiTalkServer.socket[number];//方便修改os
DataOutputStream os=new DataOutputStream(lssocket.getOutputStream());//消息,文件输出流
line="Client "+p+": "+talk[1];//把消息连接上发消息的编号,方便阅读
os.writeUTF(line);//向客户端输出该字符串
os.flush();//刷新输出流,使Client马上收到该字符串
String[] wj=talk[1].split("\\.");//"."和"|"都是转义字符,必须得加"\\";
if(wj.length>1)//如果要发文件
{
System.out.println(p+" is send file to "+number+": "+talk[1]);
int n=512,len=512;
byte[] data = new byte[n];//一次读取字节,一般不会太大
while(len>=n)
{
len=is.read(data,0,n);
os.write(data,0,len);
os.flush();
//System.out.println(len);
}
}
else
{
System.out.println(p+" is talk to "+number+": "+talk[1]);
if (talk[1].equals("bye")) {
System.out.println("客户 "+p+" 已退出系统!");
break;
}
}
}
}
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
}catch(Exception e){
System.out.println("Error:"+e);//出错,打印出错信息
}
}
}