`
jiaguwen123
  • 浏览: 415321 次
  • 性别: Icon_minigender_2
  • 来自: 深圳
社区版块
存档分类
最新评论

多线程+socket+文件读写<二>

    博客分类:
  • view
阅读更多

线程的阻塞
阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),Java 提供了大量方法来支持阻塞,下面让我们逐一分析。
    1. sleep() 方法:sleep() 允许指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间内进入阻塞状态,不能得到CPU 时间,指定的时间一过,线程重新进入可执行状态。
    2. suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume() 被调用,才能使得线程重新进入可执行状态。
    3. yield() 方法:yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。
    4. wait() 和 notify() 方法:两个方法配套使用,wait() 使得线程进入阻塞状态,它有两种形式,一种允许指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify() 被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的 notify () 被调用。
区别:
初看起来 wait() 和 notify()与 suspend() 和 resume() 方法对没有什么分别,但是事实上它们是截然不同的。区别的核心在于,前面叙述的所有方法,阻塞时都不会释放占用的锁(如果占用了的话),而 wait() 和 notify()这一对方法则相反, wait() 方法导致线程阻塞,并且该对象上的锁被释放。
在上面的实例中修改:
    public static void main(String[] args) {
        Thread1 t1 = new Thread1();
        Thread ta = new Thread(t1, "A");
        Thread tb = new Thread(t1, "B");
        ta.start();
        try {
            ta.sleep(10000);
        }
        catch (Exception e) {}
       
        tb.start();
    }
在输出A的5条记录后,须等10秒,才输出B的.
若用wait(),则直接输出A,B信息.

JAVA多线程编程。用JAVA写一个多线程程序,如写四个线程,二个加1,二个对一个变量减一,输出。(须考虑同步)
//将要加减的变量设置为static;将加减操作及相应的变量定义在另一类中.在线程中进行调用即可.
//只要是多线程,就要考虑其同步.即要用synchrnized
class t
{
    private static int x=10;
    public synchronized void add()
    {
        x++;
        System.out.println("x="+x);
    } 
    public synchronized void jian()
    {
        x--;
        System.out.println("x="+x);
    }
}
class t1 extends Thread
{
 public void run()
 {
  t t1=new t();
  t1.add();
 }     
}
class t2 extends Thread
{
 public void run()
 {
  t t1=new t();
  t1.jian();
 }
}
public class ThreadTest
{
    public static void main(String [] args)
    {
        t1 t11=new t1();
        t1 t12=new t1();
        t2 t21=new t2();
        t2 t22=new t2();
        t11.start();
        t12.start();
        t21.start();
        t22.start();
    }
}
5.
线程池
线程池就像数据库连接池一样,是一个对象池。所有的对象池都有一个共同的目的,那就是为了提高对象的使用率,从而达到提高程序效率的目的.
多线程---守护线程
在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)
        Daemon的作用是为其他线程的运行提供便利服务,比如垃圾回收线程就是一个很称职的守护者。
6.
终止线程三种方式:
当run方法完成后线程终止;
使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果);
使用interrupt方法中断线程.
 

------------------------------------文件读写----------------------------------
I/O操作
对于输入/输出问题,Java将之抽象化为流(Stream)对象来解决。
对输入/输出流,及文件的处理,注意要在最后关闭流或文件,且在处理前后添加try..catch.
Reader、Writer与其子类可以用于进行所谓纯文本文件的字符读/写.
InputStreamReader和OutputStreamWriter (它们分别为Reader和Writer的子类.)
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream); 
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);
            int ch = 0;   
            // 以字符方式显示文件内容   
            while ((ch = inputStreamReader.read()) != -1) {   
                outputStreamWriter.write(ch);   
            }   
            inputStreamReader.close();   
            outputStreamWriter.close();   
    
FileReader和FileWriter(它们分别继承自InputStreamReader与 OutputStreamWriter)
                       操作更加简单,不用先建input/outputstream,直接将路径放上去就行.
FileReader fileReader = new FileReader("D:\\jason.txt");
FileWriter fileWriter = new FileWriter("D:\\change.txt");
BufferedReader和BufferedWriter(常用于整行读写,单字读写用上面的两类)
读写效率比较高,但须先创建InputStreamReader/OutputStreamWriter或FileReader/FileWriter作为其参数
try {   
            BufferedReader reader=new BufferedReader(new FileReader("D:\\jason.log"));
            BufferedWriter writer=new BufferedWriter(new FileWriter("D:\\change.txt"));
            String show=reader.readLine(); //读取第一行信息
            while(!show.equals("bye"))
            {
             System.out.println(show);
             writer.write(show+"\n");   //其中\n用于换行
                show=reader.readLine();   //进行循环读取
            }
            writer.flush();
            reader.close();
            writer.close();
        } catch (Exception ee) {   
            ee.printStackTrace();   
        }
注意:只有BufferedReader或BufferedInputStream,没有BufferedInputStreamReader.
说明:
BufferedReader的readline()方法,实际就是以下的样式的定制:
byte[] a=new byte[2];   --->自己定制缓存的大小,而readline(),则是原先定制好的.
.....
if((ch=A.read(a))!=-1)
{B.wirte(a)}
 

------------------------------------socket----------------------------------
socket,
对输入/输出流,及文件的处理,注意要在最后关闭流或文件,且在处理前后添加try..catch
我们可以做一个简单的 Socket 例程了 . 
服务端 : 
import java.io.*; 
import java.net.*; 
public class MyServer { 
public static void main(String[] args) throws IOException{ 
  ServerSocket server=new ServerSocket(5678); 
  Socket client=server.accept(); 
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream())); 
PrintWriter out=new PrintWriter(client.getOutputStream()); 
while(true){ 
String str=in.readLine(); 
System.out.println(str); 
out.println("has receive...."); 
out.flush(); 
if(str.equals("end")) 
break; 

client.close(); 

注意:只有BufferedReader或BufferedInputStream,没有BufferedInputStreamReader.
 
       这个程序的主要目的在于服务器不断接收客户机所写入的信息直到客户机发送 "End" 字符串就退出程序 . 并且服务器也会做出 "Receive" 为回应 . 告知客户机已接收到消息 . 
客户机代码 : 
import java.net.*; 
import java.io.*; 
public class Client{ 
static Socket server; 
public static void main(String[] args)throws Exception{ 
  server=new Socket(InetAddress.getLocalHost(),5678); 
  BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream())); 
  PrintWriter out=new PrintWriter(server.getOutputStream()); 
  BufferedReader wt=new BufferedReader(new InputStreamReader(System.in)); 
   
  while(true){ 
   String str=wt.readLine(); 
   out.println(str); 
   out.flush(); 
   if(str.equals("end")){ 
    break; 
   } 
   System.out.println(in.readLine()); 
  } 
  server.close(); 


这个程序只是简单的两台计算机之间的通讯 . 如果是多个客户同时访问一个服务器呢 ? 你可以试着再运行一个客户端 , 结果是会抛出异常的 . 那么多个客户端如何实现呢 ? 
如何实现多线程并发socket通讯:
服务端socket,负责监听socket端口,设置一个无限循环,在其中实现:将监听到的socket实例赋给线程且启动线程,由线程来完成业务逻辑.具体如下:
import java.net.*; 
import java.io.*; 
public class MultiUser extends Thread{ 
private Socket client; 
public MultiUser(Socket c){ 
  this.client=c; 

public void run(){ 
  try{   
   BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream())); 
   PrintWriter out=new PrintWriter(client.getOutputStream()); 
    //Mutil User but can't parallel 
    while(true){ 
     String str=in.readLine(); 
     System.out.println(str); 
     out.println("has receive...."); 
     out.flush(); 
     if(str.equals("end")) 
      break; 
    } 
   client.close();   
   }catch(IOException ex){ 
   }finally{ 
     
   } 
myserver.java修改如下:
public static void main(String[] args)throws IOException{ 
  ServerSocket server=new ServerSocket(5678); 
  while(true){ 
   //transfer location change Single User or Multi User 
   MultiUser mu=new MultiUser(server.accept()); 
   mu.start(); 
  } 


2.
用socket传输文件,实际就是打开文件,将内容读取发送到对方,对方获取保存到文件中。
用socket可以传输对象--ObjectInputStream/ObjectOutputStream
1.          对于普通的传输字符串,用 BufferedInputStream /BufferedOutputStream 及 os.println(), is.readline() 即可。
2.          对于文件的传输,用 FileInputStream /FileOutputStream 及 DataInputStream /DataOutputStream 及 os.write(), is.read() 即可。
3.          对于对象的传输,用 ObjectInputStream /ObjectOutputStream 及 os.writeObject(), is.readObject() 即可 .
public class FileSender {
  private ServerSocket ss = null;
  public FileSender() {
  }
  public void startSend(String filePath, int port) {
    // socket输出流
    DataOutputStream os = null;
    // 文件输入流
    DataInputStream is = null;
    // 建立socket连接
    Socket socket = null;
    try {
      // 选择进行传输的文件
      File file = new File(filePath);
      // 建立socket监听
      ss = new ServerSocket(port);
      socket = ss.accept();
      os = new DataOutputStream(socket.getOutputStream());
      // 将文件名及长度传给客户端。这里要真正适用所有平台,例如中文名的处理,还需要加工,
      // 具体可以参见Think In Java 4th里有现成的代码。
      os.writeUTF(file.getName());
      os.flush();
      os.writeLong((long) file.length());
      os.flush();
      is = new DataInputStream(new BufferedInputStream(
          new FileInputStream(filePath)));
      // 缓冲区大小
      int bufferSize = 8192;
      // 缓冲区
      byte[] buf = new byte[bufferSize];
      // 传输文件
      while (true) {
        int read = 0;
        if (is != null) {
          read = is.read(buf);
        }
        if (read == -1) {
          break;
        }
        os.write(buf, 0, read);
      }
      os.flush();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      // 关闭所有连接
      try {
        if (os != null)
          os.close();
      } catch (IOException e) {
      }
      try {
        if (is != null)
          is.close();
      } catch (IOException e) {
      }
      try {
        if (socket != null)
          socket.close();
      } catch (IOException e) {
      }
      try {
        if (ss != null)
          ss.close();
      } catch (IOException e) {
      }
    }
  }
  public static void main(String[] args) {
    new FileSender().startSend("E:\\JDK_API_1_6_zh_CN.CHM", 8821);
  }
}

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class FileIncepter {
  public FileIncepter() {
  }
  public void getFile(String savePath, String ip, int port) {
    // 建立socket连接
    Socket socket = null;
    try {
      socket = new Socket(ip, port);
    } catch (UnknownHostException e1) {
      e1.printStackTrace();
    } catch (IOException e1) {
      e1.printStackTrace();
    }
    // 建立socket输入流
    DataInputStream inputStream = null;
    try {
      inputStream = new DataInputStream(new BufferedInputStream(socket
          .getInputStream()));
    } catch (IOException e1) {
      e1.printStackTrace();
    }
    try {
      // 缓冲区大小
      int bufferSize = 8192;
      // 缓冲区
      byte[] buf = new byte[bufferSize];
      int passedlen = 0;
      long len = 0;
      // 获取文件名称
      savePath += inputStream.readUTF();
      DataOutputStream fileOut = new DataOutputStream(
          new BufferedOutputStream(new BufferedOutputStream(
              new FileOutputStream(savePath))));
      // 获取文件长度
      len = inputStream.readLong();
      System.out.println("文件的长度为:" + len + "    KB");
      System.out.println("开始接收文件!");
      // 获取文件
      while (true) {
        int read = 0;
        if (inputStream != null) {
          read = inputStream.read(buf);
        }
        passedlen += read;
        if (read == -1) {
          break;
        }
        System.out.println("文件接收了" + (passedlen * 100 / len) + "%");
        fileOut.write(buf, 0, read);
      }
      System.out.println("接收完成,文件存为" + savePath);
      fileOut.close();
    } catch (Exception e) {
      e.printStackTrace();
      return;
    }
  }
  public static void main(String[] args) {
    new FileIncepter().getFile("F:\\", "localhost", 8821);
  }
}

分享到:
评论

相关推荐

    java多线程+Socket实现的漂亮QQ

    ### Java多线程+Socket实现的漂亮QQ #### 技术要点分析 ##### 1. Java Swing Java Swing 是一个用于构建图形用户界面 (GUI) 的轻量级组件集,它为开发人员提供了丰富的功能来设计复杂的用户界面。在本项目中,...

    tkinter+多线程+socket网络登录,群聊聊天室

    在Python编程领域,构建一个基于`tkinter`的图形用户界面(GUI)应用程序,并结合多线程和`socket`网络编程技术,可以实现一个功能完善的网络登录和群聊聊天室。下面将详细介绍这些知识点。 首先,`tkinter`是...

    linux下多线程读写socket的简单例子

    在Linux操作系统中,多线程编程与网络通信的结合是一个重要的技术领域,特别是在服务器开发中。...对于初学者来说,这是一个很好的起点,通过动手实践,逐步掌握Linux多线程Socket编程的核心技巧。

    netty技术文档,socket技术 多线程

    标题"Netty技术文档,Socket技术,多线程"指出我们要讨论的是Netty框架,它与Socket编程以及多线程技术的结合。Netty是一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端...

    基于WCF多线程的SOCKET文件传输服务

    总之,基于WCF的多线程SOCKET文件传输服务是一个复杂而实用的系统,它结合了WCF的易用性和SOCKET的灵活性,通过多线程实现了高效的文件并发传输。在设计和实现过程中,需要注意服务的可扩展性、安全性以及性能优化,...

    多线程socket文件传输

    "多线程socket文件传输"是一个常见的应用场景,特别是在大数据交换、文件共享等需求中。本项目使用C语言实现了一个非阻塞的多线程socket文件传输程序,尽管可能存在一些问题,但对初学者来说,它能提供宝贵的实践...

    java socket通讯例程 多线程读写 可以同时收发不同终端的消息

    在主线程中通过控制台读取键盘...服务器在收到一个socket连接之后,把该socket保存到队列中,并对队列中的每个socket开启各自的读写线程。测试可以在不同控制台运行server和client,服务器接收消息时,会显示消息来源

    java socket多线程文件传输实例项目

    Java Socket多线程文件传输实例项目是一个典型的网络编程应用场景,主要涉及了Socket编程、多线程处理以及文件I/O操作等关键知识点。在这个项目中,开发者利用Java的Socket API实现了一个能够支持多个客户端同时进行...

    多线程socket文件传输_支持断点续传_收发消息_点对多点

    在多线程Socket文件传输中,通常会创建一个主线程负责管理连接和调度,而其他线程则分别处理文件的读写。这种方式允许并发处理多个文件传输,提高了系统的并行处理能力。对于断点续传功能,需要在客户端和服务器之间...

    VS2017实现Tcp socket多线程通信(C++)

    在本文中,我们将深入探讨如何使用Visual Studio 2017和C++来实现TCP套接字的多线程通信。TCP(传输控制协议)是一种面向连接、可靠的、基于字节流的通信协议,广泛应用于互联网上的各种服务。多线程技术则允许我们...

    C# socket 多线程多管道可断点传送大文件(附单线程单管道传送)

    本文将深入探讨C#语言中使用Socket进行多线程多管道可断点传送大文件的技术细节。Socket是网络通信的基础,它提供了进程间的通信能力,使得数据可以在不同机器间传输。 首先,我们来理解"多线程"的概念。在C#中,多...

    delphi多线程socket编程介绍

    ### Delphi多线程Socket编程介绍 随着分布式系统的广泛应用,多任务并发技术变得越来越重要。在当前基于多线程的操作系统环境下,开发并发多任务程序已成为软件开发领域的一个热点话题。Delphi作为一种强大的开发...

    C++ 实现多线程文件传输的设计与实现

    在C++11及以后的版本中,标准库提供了`&lt;thread&gt;`头文件,支持多线程编程。要创建一个新线程,可以使用`std::thread`类,如下所示: ```cpp #include &lt;thread&gt; void thread_function() { // 线程执行的代码 } int...

    C# socket多线程编程

    【C# Socket 多线程编程】在C#中,Socket编程是实现网络通信的关键,特别是在多线程环境中,能够高效地处理并发连接和数据传输。Socket是TCP/IP协议的基础,它代表了通信的两端点,允许不同主机或同一主机内的进程...

    异步和多线程socket通讯

    本文将深入探讨"异步和多线程socket通讯"这一主题,基于提供的描述和标签,我们将讨论如何利用多线程和异步机制来提升socket通信的效率和响应性。 首先,Socket是一种在应用程序与网络服务之间建立连接的接口,它...

    基于Java+socket实现多线程聊天室-控制台版.rar

    在本项目"基于Java+socket实现多线程聊天室-控制台版"中,开发者创建了一个简单的、基于命令行界面的多人聊天应用。这个应用利用了Java编程语言以及Socket网络编程技术来实现实时的通信功能。以下是关于这个项目的...

    JAVA写的多线程socket通信程序源码

    在Java编程领域,多线程Socket通信是一种常见且重要的网络编程技术。Socket是TCP/IP协议栈中的一个关键组件,用于在网络中实现进程间的通信。在这个名为"JAVA写的多线程socket通信程序源码"的项目中,我们可以看到...

    VC_Socket_多线程文件传输

    《VC_Socket_多线程文件传输》是一个基于C++实现的项目,它演示了如何在Windows环境下使用Visual Studio 2005进行多线程的文件上传与下载功能。这个项目的核心技术主要包括Socket编程、多线程处理以及文件操作,这些...

    socket 一个服务器对应多个客户端使用多线程

    这个程序可能包含了上述步骤的代码实现,通过分析和学习这个示例,开发者可以更好地理解和掌握多线程Socket编程。 总的来说,使用Socket和多线程技术,我们可以构建出能够高效处理多个客户端请求的服务器。这种模型...

    Java JDK实例宝典

    7 一个支持多线程的服务器框架 &lt;br&gt;13. 8 代理服务器 &lt;br&gt;13. 9 Telnet客户端 &lt;br&gt;13. 10 UDP编程 &lt;br&gt;13. 11 聊天室服务器端 &lt;br&gt;13. 12 聊天室客户端 &lt;br&gt;13. 13 FTP客户端 &lt;br&gt;第14章 数据库 &lt;br&gt;14. 1 连接各种...

Global site tag (gtag.js) - Google Analytics