码迷,mamicode.com
首页 > 编程语言 > 详细

02--Java TCP Socket编程

时间:2017-01-16 18:27:13      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:equal   链路层   url   alt   连接   mem   sed   输入流   static   

一、基础知识

1. TCP状态转换知识,可参考:

http://www.cnblogs.com/qlee/archive/2011/07/12/2104089.html

2. TCP/IP五层模型

            应用层:HTTP、FTP、SMTP、Telnet等
            传输层:TCP/IP
            网络层:
            数据链路层:
            物理层:网线、双绞线、网卡等

3. 常用类,java.net.*

此包下主要类结构图如下:

技术分享

 

3.1 InetAddress

InetAddress类用于标识网络上的硬件资源,标识互联网协议(IP)地址。 该类没有构造方法,由于涉及DNS解析,该类一般用单例模式。

技术分享
1 //获取本机的InetAddress实例
2 InetAddress address =InetAddress.getLocalHost();
3 address.getHostName();//获取计算机名
4 address.getHostAddress();//获取IP地址
5 byte[] bytes = address.getAddress();//获取字节数组形式的IP地址,以点分隔的四部分
6 
7 //获取其他主机的InetAddress实例
8 InetAddress address2 =InetAddress.getByName("其他主机名");
9 InetAddress address3 =InetAddress.getByName("IP地址");
View Code

3.2 URL类

 URL(Uniform Resource Locator)统一资源定位符,表示Internet上某一资源的地址,协议名:资源名称

技术分享
 1 //创建一个URL的实例
 2 URL baidu =new URL("http://www.baidu.com");
 3 URL url =new URL(baidu,"/index.html?username=tom#test");//?表示参数,#表示锚点
 4 url.getProtocol();//获取协议
 5 url.getHost();//获取主机
 6 url.getPort();//如果没有指定端口号,根据协议不同使用默认端口。此时getPort()方法的返回值为 -1
 7 url.getPath();//获取文件路径
 8 url.getFile();//文件名,包括文件路径+参数
 9 url.getRef();//相对路径,就是锚点,即#号后面的内容
10 url.getQuery();//查询字符串,即参数
View Code

3.3 Socket类

代表通讯过程中的客户端。

3.4 ServerSocket类

代表通讯过程中的服务器端。

 

二、Socket编程模型及步骤

1. Socket模型图

技术分享

2. ServerSocket工作步骤

① 创建ServerSocket对象,绑定监听端口
② 通过accept()方法监听客户端请求,此处会堵塞。
③ 连接建立后,通过输入流读取客户端发送的请求信息
④ 通过输出流向客户端发送乡音信息
⑤ 关闭相关资源

3. Socket工作步骤

① 创建ServerSocket和Socket
② 打开连接到Socket的输入/输出流
③ 按照协议对Socket进行读/写操作
④ 关闭输入输出流、关闭Socket

 

三、常用工作模型

1. 服务器单线程监听和处理服务,客户端单线程,2个文件

 

技术分享
package com.yyn.io.net;

import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Date;

public class SingleThreadServer extends Thread{
 /**
  *  单线程的,仅仅是能够应答连接的客户就立即断开连接了   
  */
    private static ServerSocket serverSocket;

    public SingleThreadServer(){
        super();
        try{
            serverSocket = new ServerSocket(1112);
            System.out.println("SingleThreadSocket creating....");
        }catch (Exception e) {
            System.out.println("SingleThreadSocket create failed....");
            System.exit(1);
        }
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        Socket client = null;
        while (true) {
            if (serverSocket == null) {
                return;
            }
            try{
                client = serverSocket.accept();
                InputStream in = client.getInputStream();
                OutputStream out = client.getOutputStream();
                BufferedOutputStream bos = new BufferedOutputStream(out);
                PrintWriter writer = new PrintWriter(bos);
                Date now = new Date(System.currentTimeMillis());
                writer.write(now.toString());
                System.out.println("New Connection Accepted:"+client.getRemoteSocketAddress());
                writer.flush();
                client.close();
                
            }catch (Exception e) {
                // TODO: handle exception
            }
        }
    }
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SingleThreadServer server = new SingleThreadServer();
        server.start();
    }
}
View Code

 

技术分享
package com.yyn.io.net;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.Buffer;

public class SingleThreadClient {

    public static void main(String[] args) throws UnknownHostException, IOException {
        // TODO Auto-generated method stub
        Socket server = new Socket("127.0.0.1", 1112);
        OutputStream out = server.getOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(out);
        PrintWriter writer = new PrintWriter(bos);
        writer.write("Hello server!!!");
        
        InputStream in = server.getInputStream();
        InputStreamReader isr = new InputStreamReader(in);
        BufferedReader reader = new BufferedReader(isr);
        String info = null;
        info = reader.readLine();
        System.out.println("####Server Message: " + info);

        reader.close();
        isr.close();
        in.close();
        writer.close();
        bos.close();
        out.close();
        server.close();
        
    }

}
View Code

2. 服务器单线程监听,连接客户端后(ACCEPT成功后),启动新线程处理服务。

技术分享
package com.yyn.io.net;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

//获取用户连接请求,请求成功后,调用MultiThreadSeverThread进行服务
public class MultiThreadServerReceiver {

    public static final int PORT = 12002;
    
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        init();
    }
    
    public static void init() throws Exception{
        ServerSocket server = new ServerSocket(PORT);
        System.out.println("Server is started");
        int count = 0;
        while(true){
            Socket client = server.accept();
            System.out.println("Accepted at: " + client.getRemoteSocketAddress());
            MultiThreadSeverThread serverThread = new MultiThreadSeverThread(client);
            System.out.println("Start Thread to process!!!");
            serverThread.start();
            count++;
            while (count >=3) {
                return;
            }
        }
    }

}
View Code

 

技术分享
package com.yyn.io.net;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

//请求连接后,accept成功后,负责服务的线程类
public class MultiThreadSeverThread extends Thread{
        private Socket client = null;
        private PrintWriter writer = null;
        private BufferedReader reader = null;
        public static final String CHARSET = "UTF-8";
        
        public MultiThreadSeverThread(Socket client) throws Exception{
            this.client = client;
            try{
                // Init writer
                OutputStreamWriter osw = new OutputStreamWriter(client.getOutputStream(),CHARSET);
                BufferedWriter bw = new BufferedWriter(osw);
                this.writer = new PrintWriter(bw);
                
                // Init reader
                InputStreamReader isr = new InputStreamReader(client.getInputStream(),CHARSET);
                this.reader = new BufferedReader(isr);
            }catch(Exception e){
                e.printStackTrace();
                throw new Exception("Init MultiThreadServerThread failed!!!");
            }
            System.out.println("#######Welcome to server,input commands please!!!");
        }

        @Override
        public void run(){
            String command = null;
            boolean flag = true;
            System.out.println("thread to process!!!");
            while (flag) {
                try {
                    command = this.reader.readLine();
                    System.out.println("client command:" + command);
                } catch (Exception e) {
                    e.printStackTrace();
                    flag = false;
                }
                if (command == null) {
                    return ;
                }
                // if command is not null ,then trim it and change to upper case
                command = command.trim().toUpperCase();
                if(command.equals("QUIT")){
                    flag = false;
                }else if (command.equals("HELP")) {
                    this.writer.println("本服务器可收到的请求有:");
                    this.writer.println("list");
                    this.writer.println("push");
                    this.writer.println("pop");
                }else if(command.equals("LIST") || command.equals("PUSH") || command.equals("POP")) {
                    this.writer.println("输入命令正确");
                }else{
                    this.writer.println("输入命令有误,请重新输入!!!");
                }
                writer.flush();
            }
            // close socket connection
            try {
                this.client.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }                
        }    
}
View Code
技术分享
package com.yyn.io.net;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.stream.Stream;

public class MultiThreadServerClient {

    public static final int PORT = 12002;
    
    public static void main(String[] args) throws UnknownHostException, IOException {
        // TODO Auto-generated method stub
        Socket socket = new Socket("127.0.0.1",PORT);
        // in stream from console
        InputStreamReader isr = new InputStreamReader(System.in,"UTF-8");
        BufferedReader in = new BufferedReader(isr);
        // out stream from socket
        OutputStreamWriter osw = 
                new OutputStreamWriter(new BufferedOutputStream(socket.getOutputStream()), "UTF-8");
        PrintWriter out = new PrintWriter(osw);

        String command = null;
        while(true){
            System.out.println("#######################");
            command = in.readLine();
            if (command == null) {
                socket.shutdownInput();
                break;
            }
            command = command.trim().toUpperCase();
            if (command.equals("EXIT")) {
                socket.shutdownInput();
                break;
            }
            out.println(command); //必须用println方法,不能用write,否则服务端无法获取数据,会堵塞
            out.flush();    
            System.out.println("data send to server:"+command);    
        }
    }

}
View Code

 

 3. 服务器一次向多个客户端发送信息

 

 

 

 

 

 

02--Java TCP Socket编程

标签:equal   链路层   url   alt   连接   mem   sed   输入流   static   

原文地址:http://www.cnblogs.com/ulli/p/6282288.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!