文档章节

Java socket网络编程

天呀鲁哇
 天呀鲁哇
发布于 2015/04/03 18:14
字数 1860
阅读 57
收藏 2

1,网络基础和软件编程

     软件编写人员不需要了解太多的网络知识(基础还是需要的);软件编写人员主要抓住几点就可以做网络编程;

        1,信息传输都是0和1的传输;

        2,信息传输需要遵照网络协议;(底存的网络协议   和传输格式协议)

        3,抓住传输协议的要点(如  协议的用途   简要协议实现方式)

        4,IO

    注:有很软件编程人员通常都不知道什么是协议,抓不到协议重点;有些时候在对接的时候问他们使用的什么协议,统一回复tcp/ip协议;这让我很是蛋疼;

    补充:OSI(Open System Interconnection)开放式互联协议模型

                        分为7层:1.物理层 2.数据链路层 3.网络层 4.传输层 5.会话层 6.表示层 7.应用层

             TCP/IP协议模型:

                        分为4层: 1.网络接口层,2.互联网层 3.传输层 4.应用层

            协议都是分层的,我们常用的都是应用层协议;如htpp协议;

            什么是协议?协议规定了我们在网络传输中的格式样板;

        

2,Java网络编程Socket

   

1,什么是Socket

网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个SocketSocket通常用来实现客户方和服务方的连接。SocketTCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。

但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。

2Socket通讯的过程

ServerListen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过SendWrite等方法与对方通信。

对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:

  (1 创建Socket

  (2 打开连接到Socket的输入/出流;

  (3 按照一定的协议对Socket进行读/写操作;

  (4 关闭Socket.(在实际应用中,并未使用到显示的close,虽然很多文章都推荐如此,不过在我的程序中,可能因为程序本身比较简单,要求不高,所以并未造成什么影响。)

3,创建Socket

创建Socket

java在包java.net中提供了两个类SocketServerSocket,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用很方便。其构造方法如下:

  Socket(InetAddress address, int port);

  Socket(InetAddress address, int port, boolean stream);

  Socket(String host, int prot);

  Socket(String host, int prot, boolean stream);

  Socket(SocketImpl impl)

  Socket(String host, int port, InetAddress localAddr, int localPort)

  Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

  ServerSocket(int port);

  ServerSocket(int port, int backlog);

  ServerSocket(int port, int backlog, InetAddress bindAddr)

  其中addresshostport分别是双向连接中另一方的IP地址、主机名和端 口号,stream指明socket是流socket还是数据报socketlocalPort表示本地主机的端口号,localAddr bindAddr是本地机器的地址(ServerSocket的主机地址),implsocket的父类,既可以用来创建serverSocket又可 以用来创建Socketcount则表示服务端所能支持的最大连接数。例如:学习视频网 http://www.xxspw.com

  Socket client = new Socket("127.0.01.", 80);

  ServerSocket server = new ServerSocket(80);

  注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才 能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23, 所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。

  在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建SocketServerSocket是必须捕获或抛出例外。

package com.dom.socket;

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

public class ServiceDom {

    public static void main(String[] args){
        try {
            ServerSocket server = new ServerSocket(8082);
            Socket socket = server.accept();
            //获得服务端套接字的输入输出流
            Reader reader = new InputStreamReader(socket.getInputStream());  
              char chars[] = new char[64];  
              int len;  
              StringBuilder sb = new StringBuilder();  
              while ((len=reader.read(chars)) != -1) {  
                 sb.append(new String(chars, 0, len));  
              }  
              System.out.println("from client: " + sb);  
              reader.close();  
              socket.close();  
              server.close(); 
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
    
}
package com.dom.socket;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientDom {

    public static void main(String [] ags){
        
        try {
            Socket socket = new Socket("127.0.0.1",8082);
            Writer writer = new OutputStreamWriter(socket.getOutputStream());
            writer.write("my socket dom");
            writer.flush();
            writer.close();  
            socket.close(); 

        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
}

    

使用socket实现http协议传输消息

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;

/**
 * 一个简单的HTTP客户端,发送HTTP请求,模拟浏览器
 * 可打印服务器发送过来的HTTP消息
 */
public class SimpleHttpClient {
    private static String encoding = "GBK";

    public static void main(String[] args) {
        try {
            Socket s = new Socket(InetAddress.getLocalHost(), 8080);
            OutputStreamWriter osw = new OutputStreamWriter(s.getOutputStream());
            StringBuffer sb = new StringBuffer();
            sb.append("GET /HttpStream/gb2312.jsp HTTP/1.1\r\n");
            sb.append("Host: localhost:8088\r\n");
            sb.append("Connection: Keep-Alive\r\n");
            sb.append("\r\n");
            osw.write(sb.toString());
            osw.flush();

            //--输出服务器传回的消息的头信息
            InputStream is = s.getInputStream();
            String line = null;
            int contentLength = 0;//服务器发送回来的消息长度
            // 读取所有服务器发送过来的请求参数头部信息
            do {
                line = readLine(is, 0);
                //如果有Content-Length消息头时取出
                if (line.startsWith("Content-Length")) {
                    contentLength = Integer.parseInt(line.split(":")[1].trim());
                }
                //打印请求部信息
                System.out.print(line);
                //如果遇到了一个单独的回车换行,则表示请求头结束
            } while (!line.equals("\r\n"));

            //--输消息的体
            System.out.print(readLine(is, contentLength));

            //关闭流
            is.close();

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * 这里我们自己模拟读取一行,因为如果使用API中的BufferedReader时,它是读取到一个回车换行后
     * 才返回,否则如果没有读取,则一直阻塞,直接服务器超时自动关闭为止,如果此时还使用BufferedReader
     * 来读时,因为读到最后一行时,最后一行后不会有回车换行符,所以就会等待。如果使用服务器发送回来的
     * 消息头里的Content-Length来截取消息体,这样就不会阻塞
     * 
     * contentLe 参数 如果为0时,表示读头,读时我们还是一行一行的返回;如果不为0,表示读消息体,
     * 时我们根据消息体的长度来读完消息体后,客户端自动关闭流,这样不用先到服务器超时来关闭。
     */
    private static String readLine(InputStream is, int contentLe) throws IOException {
        ArrayList lineByteList = new ArrayList();
        byte readByte;
        int total = 0;
        if (contentLe != 0) {
            do {
                readByte = (byte) is.read();
                lineByteList.add(Byte.valueOf(readByte));
                total++;
            } while (total < contentLe);//消息体读还未读完
        } else {
            do {
                readByte = (byte) is.read();
                lineByteList.add(Byte.valueOf(readByte));
            } while (readByte != 10);
        }

        byte[] tmpByteArr = new byte[lineByteList.size()];
        for (int i = 0; i < lineByteList.size(); i++) {
            tmpByteArr[i] = ((Byte) lineByteList.get(i)).byteValue();
        }
        lineByteList.clear();

        return new String(tmpByteArr, encoding);
    }
}

    上面都是采用的是io;因为NIO的缘故  这些代码都不是自己写的;后面准备自己写NIO的实现;(就这一点东东就花了了我一天时间   真心伤不起呀;基础   基础  基础夯实真的很重要)   在此记录以备后用

© 著作权归作者所有

上一篇: java.nio
天呀鲁哇
粉丝 8
博文 98
码字总数 42007
作品 0
长宁
程序员
私信 提问
操作系统,windows编程,网络,socket

首发:个人博客,更新&纠错&回复 之前关于c/s的一篇博文只记了思路没记代码,而且表达不清晰,事后看不知所云,这个习惯要改。 这十几天学了点关于操作系统、windows编程和网络,主要看的书有...

祁达方
2015/11/11
149
0
基于tcp和udp的socket实现

本文介绍如何用Java实现Socket编程。首先介绍Java针对Socket编程提供的类,以及它们之间的关系。然后分别针对TCP和UDP两种传输层协议实现Socket编程。 1 Java中的Socket编程接口介绍 Java为S...

chjuaner
2017/11/07
82
0
Java网络编程方面有关问题

Java netty方面的知识吗? 有谁能教教我~ 因为对Java 网络编程深入比较少,所以项目停滞不前,测试压力通不过。。很让人头疼。 服务是这样定义的,首先发绑定包到服务端,然后心跳保持包,其...

MrLovelyCbb
2010/11/24
754
15
java基础专栏—java网络编程

java网络编程 在网络成层中TCP对应于四层 通常是对网络连接设备的驱动协议,例如对光纤和都对网线的驱动不一样 TCP/IP协议的核心,他用于将数据分组 包括TCP,UDP 主要是负责应用程序的协议。...

T-newcomer
2017/10/25
91
0
什么是Java语言?java语言简介

Java是由Sun Microsystems公司于1995年5月推出的Java程序设计语言(以下简称Java语言)和Java平台的总称。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动态的W...

阿秀a
2010/10/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

sync 包讲解

sync.Once Once 的作用是多次调用但只执行一次,Once 只有一个方法,Once.Do(),向 Do 传入一个函数,这个函数在第一次执行 Once.Do() 的时候会被调用,以后再执行 Once.Do() 将没有任何动作...

李琼涛
23分钟前
4
0
java中的byte占一字节或4字节

https://www.jianshu.com/p/2f663dc820d0

南桥北木
37分钟前
5
0
Cassandra 常用命令

Linux控制台命令 #进入Cassandra的安装目录 cd /home/db/cassandra/cassandra #进入Cassandra 无密码 ./bin/cqlsh localhost(IP)有密码 ./bin/cqlsh localhost(IP)-u 用户名 #显示所...

最菜最菜之小菜鸟
42分钟前
6
0
自建redis笔记

自建redis笔记 最近在linux安装了一下redis,特做一些笔记! 本文先单节点启动redis,然后再进行持久化配置,在次基础上,再分享搭建主从模式的配置以及Sentinel 哨兵模式及集群的搭建 单节点...

北极之北
50分钟前
5
0
扛住阿里双十一高并发流量,Sentinel是怎么做到的?

Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景 本文介绍阿里开源限流熔断方案Sentinel功能、原理、架构、快速入门以及相关框架比较 基本介绍 1 名词解释 服务限流 :当系统资源...

分布式系统架构
58分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部