网络编程(1)之socket编程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_23490433/article/details/89220211

1、什么是网络编程?

网络编程就是2个或多个设备之间进行数据交换。数据之间的传递本身没有多大的难度,无非就是将一个设备中的数据发送给另外一个设备,然后接收另外一个设备反馈过来的数据。

在网络编程中,都是基于请求/响应方式的,

发起连接程序,也就是第一次请求的程序,被称作为客户端(client)

等待其它程序连接的程序被称之为服务器(server).

注:客户端程序在需要的时候启动,而服务端程序为了能够时刻响应连接,则需要一直启动。

例如打电话,首先拨号的人类似于客户端,而接听电话的人必须保持电话畅通类似于服务器。连接一旦建立成功,服务端和客户端就可以进行数据传递了。

2、网络模型

网络模型分为:OSI参考模型和TCP/IP参考模型,如下图:

3、网络通讯3要素:传输协议、ip地址、端口号

1)、传输协议:就是通讯的规则,常见的协议如:TCP、UDP

2)、IP地址:InetAddress,就是网络中设备的标识,如本地地址:127.0.0.1,主机名:localhost

3)、端口号:用于标识进程的逻辑地址,不同进程的标识,有效端口为0-65535,其中0-1024是系统使用或保留的端口

4、TCP和UDP的区别:

1)、传输数据限制:TCP对传输的数据没有大小限制

                                UDP的每个数据包的大小限制在64k以内

2)、是否连接:Tcp需要建立连接,形成传输的数据通道

                            UDP将数据源和目的地封装到数据包中,不需要建立连接

3)、传输是否可靠:TCP通过三次握手完成连接,是可靠协议

                                   UDP因无需建立连接,是不可靠协议

4)、速度:TCP必须建立连接,效率会稍低

                     UDP无需建立连接,速度快

应用场景:tcp如:电话通话,必须连接,对方同意才可以发送数据(不然就等待),不能丢失数据。

                  udp如:聊天、对讲机就是udp的,它是面向无连接(不管在不在,知不知道,只管发送,求速度),丢数据也不管。速度

                  快,数据被分成包

5、InetAddress与Socket常用类和方法

InetAddress:构造方法私有,不能直接创建对象

InetAddress getByName(String host):在给定主机名的情况下,确定主机的ip地址

InetAddress getLocalHost():返回本地主机

inetAddress.getHostAddress():得到主机地址

inetAddress.getHostName():得到主机名称

6、什么是socket?

socket就是为网络服务提供的一种机制

通信的两端都有socket

网络通信其实就是socket间的通信

数据在两个socket之间通过IO传输

7、TCP传输

在BIO中,2个端点建立连接后会有一个传输数据的通道,这个通道就是流,而且是建立在网络基础上的流,称之为socket流。

该流中既有读取,也有写入。

2)、tcp的2个端点,一个是客户端,对应的对象是Socket

                                一个是服务端,对应的对象是ServerSocket

3)、tcp客户端创建步骤,如下:

步骤1、建立tcp的socket服务,最好明确具体的地址和端口。

             这个对象创建时,就已经对指定ip和端口进行连接(三次握手)

步骤2、如果连接成功,就意味着通道建立了,socket流就已经产生了。

             只要获取到socket流中的读取流和写入流即可,只要通过getInputStream和getOutputStream就可以获取这2个流对象

步骤3、关闭资源

代码如下:

package com.cn.io;

import java.io.*;
import java.net.Socket;
/**
 * 客户端向服务器端发送一个数
 * */
public class SocketClient {
    public static void main(String[] args) throws Exception{
        Socket socket=new Socket("localhost",8532);
        OutputStream os=socket.getOutputStream(); //获取了socket流中的输出流对象
        os.write("hello,我是来自客户端的请求dsdsdsds".getBytes());
        socket.close();
    }
}

Tcp服务端创建步骤如下

第一步、创建服务端socket对象ServerSocket,并监听一个端口

第二步、服务端为了给客户端提供服务,获取客户端的内容,可以通过accept方法获取连接过来的客户端对象

第三步、可以通过获取到的socket对象中的socket流和具体的客户端进行通讯

第四步、如果通讯结束,关闭资源。注意:要先关闭客户端,再关闭服务端

代码如下:

package com.cn.io;

import sun.applet.Main;

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

public class SocketServer {
    public static void main(String[] args) throws IOException {
        //1.获取服务器端socket,并监听端口
        ServerSocket serverSocket=new ServerSocket(8532);
        //2.获取客户端对象
        Socket socket=serverSocket.accept();
        //3.获取socket对象中的socket流和具体的客户端进行通讯
        InputStream is=socket.getInputStream();
        //4.读取客户端的数据,使用客户端对象的socket读取流
        byte[] b=new byte[1024];   //定义一个byte类型的数组,数组长度为1024
        int len=is.read(b);       //通过输入流读取数组中的数据
        String text=new String(b,0,len); //byte数组b从下标为0开始前进len个下标的那一段数组变为字符串text
        System.out.println(text);
        //如果通讯结束,关闭资源,注意要先关闭客户端,再关闭服务端
        socket.close();
        serverSocket.close();
    }
}

总结:对于UDP和TCP,既可以定义输出流也可以创建输入流,具体的情况根据需要构建。

比如:我们需要客户端给服务端发送数据,服务端在给客户端响应数据,那么就要在客户端和服务器端分别多加一个输入流和输出流,否则,发布出去、收不到。

代码如下:

客户端:

package com.cn.io;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class Client {
    public static void main(String[] args) throws Exception {
        //1.获得客户端socket
        Socket socket=new Socket("localhost",8901);
        //2.获得输出流
        OutputStream os=socket.getOutputStream();
        //3.输出消息到服务端
        os.write("你好,我是服务端消息".getBytes());
        //关闭socket
        socket.shutdownOutput();
        //4.得到输入的消息
        InputStream is=socket.getInputStream();
        byte[] b=new byte[1024];
        int len=is.read(b);
        System.out.println(new String(b,0,len));
        //关闭
        socket.close();
    }
}

服务器端:

package com.cn.io;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws Exception{
        //1.获得服务器端socket,并监听端口
        ServerSocket serverSocket=new ServerSocket(8901);
        //2.获取客户端对象
        Socket socket=serverSocket.accept();
        //3.获得客户端输入流
        InputStream is=socket.getInputStream();
        //4.声明一个byte类型的数组,数组长度为1024
        byte[] b=new byte[1024];
        int len;
        while((len=is.read(b))!=-1){
            System.out.println(new String(b,0,len));
        }
        //5.因为是双向通信的,可以在此处定义一个输出流,输出数据到服务器端
        OutputStream os=socket.getOutputStream();
        os.write("你好,我是来自服务端的消息".getBytes());
        //6.关闭,先关闭客户端,再关闭服务端
        socket.close();
        serverSocket.close();

    }
}

猜你喜欢

转载自blog.csdn.net/sinat_23490433/article/details/89220211