java网络编程初步理解

来源:互联网 发布:遗传算法参考书 编辑:程序博客网 时间:2024/06/04 19:48

几个关键类

  1. ServerSocket
  2. Socket
  3. InetAddress

ServerSocket

ServerSocket类用于在服务机上的对应端口创建可被客户端连接的接口。

常用构造器
ServerSocket(int port); 创建ServerSocket , 并绑定到本机的port端口上
ServerSocket server = new ServerSocket(8888);
常用方法
Socket accept(); 阻塞线程等待客户端的访问,有客户端访问后将与客户端相关联的Socket返回

void close(); 关闭serverSocket

Socket

Socket类用于服务端和客户端进行数据传送。

InetAddress 

存有ip地址信息

Socket编程Hello World

服务器
package me.paul.socket;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class Server {private final ServerSocket serverSocket;public Server(int port) throws IOException{serverSocket = new ServerSocket(port);System.out.println("服务器已创建,并等待客户端连接");Socket socket = serverSocket.accept();System.out.println("客户端:" + socket.getInetAddress().getHostAddress() + " 连接到服务器");serverSocket.close();}public static void main(String[] args) throws IOException{new Server(1234);}}
客户端
package me.paul.socket;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;public class Client {public static void main(String[] args) throws UnknownHostException, IOException{Socket socket = new Socket("localhost",1234);socket.close();}}
需要注意的是当用完ServerSocket和Socket后务必要关闭

附一副流程图



IO操作

网络编程的目的就是为了达到通信的目的。为了这个目的,就要使用socket得到io流来进行数据流的传送

  1. socket中的io类似于两根水管连接着Server和Client,他们有各自的输入和输出,方向就是图中所示的方向
  2. 图中蓝色的笑脸类似于水龙头,数据流到这里停留,直到Server/Client获取其中的数据
  3. 这里的io操作是两个进程之间的数据传送,传送的先后不能保证,所以读的一方要不断地从流中读取,才能进行正常读取

传送文件的例子

  1. 服务端等待客户端连接
  2. 客户端连接服务端
  3. 客户端发送文件请求(请求格式:fileName:xxx)
  4. 服务端如果接收到正确的请求则返回1给客户端
  5. 客户端接收到1 , 开始发送文件
  6. 服务端读取文件,写到本地
  7. 结束这一次连接
我尝试把服务端程序在阿里云服务器上运行,在本机向服务器发送一个22.6M的文件,用时大约200秒
编译运行:

md5检验文件:



服务端(省略了类的表示和Import)
private ServerSocket serverSocket;public void init() throws IOException {  try{    //创建serverSocket绑定到9999端口    serverSocket = new ServerSocket(9999);    System.out.println("Server created at " + new Date());    //用多线程允许接收多次文件    while (true) {      //等待      Socket socket = serverSocket.accept();      System.out.println("Client from ip : " + socket.getInetAddress().getHostAddress() + " connected to Server");      //创建新线程执行接收文件的任务      Thread t = new Thread(new ReceiveTask(socket));      t.start();    }  }finally{     //关闭serverSocket,回收资源     if(serverSocket != null) serverSocket.close();  }}
ReceiveTask
class ReceiveTask implements Runnable {  private Socket socket;  //传入连接的socket  ReceiveTask(Socket socket) {    this.socket = socket;  }  @Override  public void run() {    InputStream inputStream = null;    Scanner scanner = null;    OutputStream outputStream = null;    PrintWriter printWriter = null;    String path = "/";    try {      //得到流      inputStream = socket.getInputStream();      //用printWriter包装,便于输出数据      printWriter = new PrintWriter(socket.getOutputStream());      scanner = new Scanner(inputStream);      while (true) {        // 获取文件名        String str = scanner.nextLine();        System.out.println(str);        if (str == null || str.isEmpty()) {          continue;        }        if(!str.startsWith("fileName:")){          printWriter.println("请求字符串格式为:fileName:xxxx");          printWriter.flush();          continue;        }        printWriter.println("1");        printWriter.flush();        String fileName = str.split(":")[1];        //创建本地文件        File file = new File(path,fileName);        outputStream = new FileOutputStream(file);        int length = 0;        byte[] buf = new byte[4096];        //从流中读取数据,写到本地文件流中        while ((length = inputStream.read(buf)) > 0) {          outputStream.write(buf, 0, length);        }        printWriter.println("文件: " + file.getName() + "已被接收");        System.out.println("receive file : " + file.getName());        break;      }    } catch (IOException e) {      e.printStackTrace();    } finally {        try {          if(printWriter != null)            printWriter.close();          if (outputStream != null)            outputStream.close();          if (scanner != null)            scanner.close();          if (inputStream != null)            inputStream.close();          socket.close();        } catch (IOException e) {          e.printStackTrace();        }    }  }}
客户端核心代码
InputStream inputStream = null;OutputStream outputStream = null;Scanner scanner = null;PrintStream printStream = null;try {  socket = new Socket("115.28.137.210",8888);  inputStream = new FileInputStream(file);  outputStream = socket.getOutputStream();  printStream = new PrintStream(outputStream);  //将文件名发送到服务器端  printStream.println("fileName:"+file.getName());  printStream.flush();  scanner = new Scanner(socket.getInputStream());  while(true){    String str = scanner.nextLine().trim();    if(str == null || str.isEmpty()){      continue;    }    if(!str.equals("1")){      textArea.append(str + "\n");      continue;    }    int length = 0;    byte[] buf = new byte[4096];    while((length = inputStream.read(buf)) > 0){      outputStream.write(buf, 0, length);    }    textArea.append("file : " + file.getName() + " has been sent\n");    break;  }} catch (UnknownHostException e) {  e.printStackTrace();} catch (IOException e) {  e.printStackTrace();} finally{  try{    if(scanner != null) scanner.close();    if(printStream != null) printStream.close();    if(outputStream != null) outputStream.close();    if(inputStream != null) inputStream.close();    socket.close();  }catch(IOException e){  e.printStackTrace();}



Strike while the iron is hot

我的个人网站中的该文章点击打开链接

0 0
原创粉丝点击