02--Java TCP Socket编程

一、基础知识

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地址");

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();//查询字符串,即参数

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();
    }
}

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();

    }

}

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;
            }
        }
    }

}

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();
            }
        }
}

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);
        }
    }

}

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

时间: 2024-10-18 18:30:22

02--Java TCP Socket编程的相关文章

Java - TCP网络编程

Java - TCP网络编程 Server 逻辑思路: 创建ServerSocket(port),然后服务器的socket就启动了 循环中调用accept(),此方法会堵塞程序,直到发现用户请求,返回用户的socket 利用多线程对用户socket进行IO操作 注意:对Scoket/File进行创建.关闭,都需要放try catch中,检测 IOException,所以将网络IO部分整体放入try catch中即可. 1. 字符串操作 输出:PrintWriter out=new PrintWr

基于java的socket编程

#开头的废话#学习java已经半个月了,原本在抠教材里面的字眼时,觉得教材好厚,要看完不知道要到猴年马月去了.突然在网上看到一个教程,里面老师说学编程语言书不用太细看,看个大概,知道里面讲些什么就好,不用全记得,然后你一个劲地编,使劲地编,编的时候不懂再回来看就好了,这是最快的方法.心里一琢磨,还真是这样,根据以前学C语言的情况不就这样吗.所以便加速看,把一些书里介绍的方法,类飞速地浏览过了,刷到网络这一章,觉得socket编程应该是得试一下手,不要只看不做假把式. 此文为原创,转摘请注明转摘自

Go语言TCP Socket编程

Golang的主要 设计目标之一就是面向大规模后端服务程序,网络通信这块是服务端 程序必不可少也是至关重要的一部分.在日常应用中,我们也可以看到Go中的net以及其subdirectories下的包均是"高频+刚需",而TCP socket则是网络编程的主流,即便您没有直接使用到net中有关TCP Socket方面的接口,但net/http总是用到了吧,http底层依旧是用tcp socket实现的. 网络编程方面,我们最常用的就是tcp socket编程了,在posix标准出来后,s

基于java的socket编程及API解析

一.socket通讯过程 1.socket与socket编程简介: socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式.通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据. 我们所说的socket 编程,是站在传输层的基础上,所以可以使用 TCP/UDP 协议,但是不能进行访问网页,因为访问网页所需要的 http 协议位于应用层.作为一个应用程序是能实现该层以下的内容,而不能实现在该层之上的内容. 2.socket通讯过程: (

java Tcp Socket 传输图片代码

server端代码 import java.net.*; import java.io.*; public class ServerTcpListener implements Runnable{ public static void main(String[] args){ try{ final ServerSocket server = new ServerSocket(); InetAddress addr = java.net.Inet4Address.getLocalHost(); S

java网络socket编程详解

7.2 面向套接字编程    我们已经通过了解Socket的接口,知其所以然,下面我们就将通过具体的案例,来熟悉Socket的具体工作方式 7.2.1使用套接字实现基于TCP协议的服务器和客户机程序    依据TCP协议,在C/S架构的通讯过程中,客户端和服务器的Socket动作如下: 客户端: 1.用服务器的IP地址和端口号实例化Socket对象. 2.调用connect方法,连接到服务器上. 3.将发送到服务器的IO流填充到IO对象里,比如BufferedReader/PrintWriter

【转】java的socket编程

转自:http://www.cnblogs.com/linzheng/archive/2011/01/23/1942328.html 一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机. 而TCP层则提供面向应用的可靠(tcp)的或非可靠(UDP)的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是

Java UDP Socket编程

UDP协议 UDP协议提供的服务不同于TCP协议的端到端服务,它是面向非连接的,属不可靠协议,UDP套接字在使用前不需要进行连接.实际上,UDP协议实现了两个功能: 1)在IP协议的基础上添加了端口: 2)对传输过程中可能产生的数据错误进行了检测,并抛弃已经损坏的数据. UDP的Java支持 Java通过DatagramPacket类和DatagramSocket类来使用UDP套接字,客户端和服务器端都通过DatagramSocket的send()方法和receive()方法来发送和接收数据,用

【JAVA】Socket 编程

对于Java Socket编程而言,有两个概念,一个是ServerSocket,一个是Socket.服务端和客户端之间通过Socket建立连接,之后它们就可以进行通信了.首先ServerSocket将在服务端监听某个端口,当发现客户端有Socket来试图连接它时,它会accept该Socket的连接请求,同时在服务端建立一个对应的Socket与之进行通信.这样就有两个Socket了,客户端和服务端各一个. 对于Socket之间的通信其实很简单,服务端往Socket的输出流里面写东西,客户端就可以