/*
客户端:
1,服务端点
2,读取客户端已有的图片数据
3,通过socket输出流将数据发给服务端
4,读取服务端反馈信息
5,关闭
*/
import java.io.*;
import java.net.*;
class PicClient //客户端
{
public static void main(String[] args)throws Exception
{
Socket s = new Socket("114.98.252.176", 10009);
FileInputStream fis = new FileInputStream("c:\\138.JPG");//关联要读取的流文件
//为了发送数据,获取socket流中的输出流
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int num = 0;
while((num=fis.read(buf)) != -1)
{
out.write(buf, 0, num);
}
//告诉服务端数据传输结束
out.shutdownOutput();
//为了接收数据,获取socket流中的输入流
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int len = in.read(bufIn);
System.out.println(new String(bufIn, 0, len));//输出信息
fis.close();
s.close();
}
}
class PicServer //服务端
{
public static void main(String[] args)throws Exception
{
ServerSocket ss = new ServerSocket(10009);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();//获取ip地址
System.out.println(ip);
//为了接收数据,获取socket流中输入流
InputStream in = s.getInputStream();
FileOutputStream fos = new FileOutputStream("serverxx.JPG");
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf)) != -1)
{
fos.write(buf, 0, len);
}
//为了输出数据,获取socket流中输出流
OutputStream out = s.getOutputStream();
out.write("接收完毕".getBytes());
fos.close();
s.close();
ss.close();
}
}
-------------------------------------------------------------------------------------------------
客户端并发上传图片::
/*
需求:上传图片
客户端:
1,服务端点
2,读取客户端已有的图片数据。
3,通过socket输出流将 数据发给服务端
4,读取服务端反馈信息
5,关闭。
*/
import java.io.*;
import java.net.*;
class PicClient
{
public static void main(String[] args)throws Exception
{
if(args.length != 1)//判断args数组是否为1
{
System.out.println("请选择一个jpg格式的图片");
return;
}
File file = new File(args[0]);//把args封装成对象
if(!(file.exists() && file.isFile()))//判断:文件存在并且是个文件
{
System.out.println("该文件有问题,要么不存在,要么有问题");
return;
}
if(!(file.getName().endsWith(".jpg")))//判断文件是否为jpg格式
{
System.out.println("图片格式错误");
}
if(file.length()>1024*1024*5)//判断文件是否大于5M
{
System.out.println("文件过大");
return;
}
Socket s = new Socket("114.98.253.36",10007);
FileInputStream fis = new FileInputStream(file);
//为了发送数据,获取socket流中的输出流
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf)) != -1)
{
out.write(buf,0,len);
}
//告诉服务端数据已经写完
s.shutdownOutput();
//为了接收数据,获取socket流中的输入流
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int num = in.read(bufIn);
System.out.println(new String(bufIn,0,num));
fis.close();
s.close();
}
}
/*
服务端
这个服务端有个局限性,当A客户端连接上以后,被服务端获取到,
服务端执行具体流程。这时B客户端连接,只有等待。
因为服务端还没有出来完客户端A的请求,还没有循环回来
执行下次accept方法。暂时获取不到B客户端对象。
那么为了可以让多个客户端同时被服务端同时并发访问服务端。
那么服务端最好就是将每个客户端封装到一个单独的线程中,
这样,就可以同时处理多个客户端请求。
如何定义线程呢?
只要明确了每一个客户端要在服务端执行的代码即可。将该
代码存入run方法中。
*/
class PicThread implements Runnable
{
private Socket s;
PicThread(Socket s)
{
this.s = s;
}
public void run()
{
String ip = s.getInetAddress().getHostAddress();
try
{
int count = 1;//定义计数器,为了给图片命名
System.out.println(ip+"...");
//为了接收数据,获取socket流中的输入流
InputStream in = s.getInputStream();
File file = new File(ip+"("+(count)+")"+".JPG");//为文件命名
while(file.exists())// 判断文件是否存在
file = new File(ip+"("+(count++)+")"+".JPG");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf)) != -1)
{
fos.write(buf,0,len);
}
//为了输出数据,获取socket流中输出流
OutputStream out = s.getOutputStream();
out.write("上传成功".getBytes());
fos.close();
s.close();
}
catch(Exception e)
{
throw new RuntimeException(ip+"上传失败");
}
}
}
class PicServer
{
public static void main(String[] args)throws Exception
{
ServerSocket ss = new ServerSocket(10007);
while(true)
{
Socket s = ss.accept();
new Thread(new PicThread(s)).start();
}
//ss.close();
}
}
----------------------------------------------------------------------------
/*
客户端通过键盘录入用户名。
服务端对这个用户名进行校验。
如果该用户存在,在服务端显示xxx,已登录。
并在客户端显示xxx,欢迎光临。80
如果该用户存在,在服务端显示xxx,尝试登陆。
并在客户端显示xxx,该用户不存在。
最多就登陆三次
*/
import java.io.*;
import java.net.*;
class LoginClient
{
public static void main(String[] args)throws Exception
{
Socket s = new Socket("114.98.253.36",10008);
//读取键盘录入
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
//改变默认输出流,把数据输出socket输出流中
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
//获取服务端反馈信息
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
for(int x=0; x<3; x++)//客户端限定读取三次
{
String line = bufr.readLine();//读取键盘录入
if(line == null)
break;
out.println(line);//向服务端发送数据
String info = bufIn.readLine(); //读取服务端反馈信息
System.out.println("info: "+info);
if(info.contains("欢迎"))//判断限定次数已经登陆成功,
break;
}
bufr.close();
s.close();
}
}
class UserThread implements Runnable
{
private Socket s;
UserThread(Socket s)//封装客户端线程
{
this.s = s;
}
public void run()
{
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....connnected");
try
{
for(int x=0; x<3; x++)
{
//获取客户端输入的用户名
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String name = bufIn.readLine();
if(name==null)
break;
//读取文件中用户名信息
BufferedReader bufr = new BufferedReader(new FileReader("user.txt"));
//服务端反馈信息到客户端
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String line = null;
boolean flag = false;// 定义一个标记
while((line=bufr.readLine()) != null)//读取一行校验一次
{
if(line.equals(name)) //判断
{
flag = true;
break;
}
}
if(flag)
{
System.out.println(name+",已登录");
out.println(name+",欢迎光临");//向客户端反馈信息
break;
}
else
{
System.out.println(name+",尝试登录");
out.println(name+",用户名不存在!!!");//向客户端反馈信息
}
}
s.close();
}
catch(Exception e)
{
throw new RuntimeException(ip+"检验失败");
}
}
}
class LoginServer
{
public static void main(String[] args)throws Exception
{
ServerSocket ss = new ServerSocket(10008);
while(true)
{
Socket s = ss.accept();
new Thread(new UserThread(s)).start();
}
}
}
------------------------------------------------------------------------------------------------------------
个人总结: