网络编程—07—上传图片 并发登陆

 

/*
客户端:
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(); 
  }
 } 
}
------------------------------------------------------------------------------------------------------------

个人总结:
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值