Socket 网络编程

Sokcet网络编程

一:什么是网络编程?

现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数据给另外一个,然后接收另一个设备的反馈。

  在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端(Client),等待其他程序连接的程序被称作服务器(Server)。客户端程序可以在需要的时候启动,而服务器为了能够时刻相应连接,则需要一直启动。例如以打电话为例,首先拨号的人类似于客户端,接听电话的人必须保持电话畅通类似于服务器。

IP地址和域名

  IP地址是一个规定,现在使用的是IPv4,既由4个0-255之间的数字组成,在计算机内部存储时只需要4个字节即可。在计算机中,IP地址是分配给网卡的,每个网卡有一个唯一的IP地址,如果一个计算机有多个网卡,则该台计算机则拥有多个不同的IP地址,在同一个网络内部,IP地址不能相同。IP地址的概念类似于电话号码、身份证这样的概念。

  由于IP地址不方便记忆,所以有专门创造了域名(Domain Name)的概念,其实就是给IP取一个字符的名字,例如163.com、sina.com等。IP和域名之间存在一定的对应关系。如果把IP地址类比成身份证号的话,那么域名就是你的姓名。

  其实在网络中只能使用IP地址进行数据传输,所以在传输以前,需要把域名转换为IP,这个由称作DNS的服务器专门来完成。

  所以在网络编程中,可以使用IP或域名来标识网络上的一台设备。

端口的概念

为了在一台设备上可以运行多个程序,人为的设计了端口(Port)的概念,类似的例子是公司内部的分机号码。

每个网络程序,无论是客户端还是服务器端,都对应一个或多个特定的端口号。由于0-1024之间多被操作系统占用,所以实际编程时一般采用1024以后的端口号。使用端口号,可以找到一台设备上唯一的一个程序。

  所以如果需要和某台计算机建立连接的话,只需要知道IP地址或域名即可,但是如果想和该台计算机上的某个程序交换数据的话,还必须知道该程序使用的端口号。


 小结

 网络编程就是使用IP地址,或域名,和端口连接到另一台计算机上对应的程序,按照规定的协议(数据格式)来交换数据,实际编程中建立连接和发送、接收数据在语言级已经实现,做的更多的工作是设计协议,以及编写生成和解析数据的代码罢了,然后把数据转换成逻辑的结构显示或控制逻辑即可。

网络模型图

 

有时候面试官会问你:http协议是属于那一层,是属于应用层,我们经常javaee的开发也是基本属于应用层的开发.



什么是Socket

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

通讯的两端都有Sokcet,

网络通讯其实就是Sokcet间的通讯,数据在两个Sokcet间通过IO传输。


如果对于TCP这一块还不是很了解的话,建议看一下我的另一篇博文:   

关于网络通讯/Tcp 基础知识    地址:   http://mp.blog.csdn.net/postedit/79158232 


我们通过三个简单案例来对socket有进一步的了解

案例1 :通过UDP协议实现课程案例,客户端与服务器端进行传输

实现UDP客户端发送代码

package com.dudu.lizhen.socket.udpsocket;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

/**
 * UDP连接客户端
 * 思路
 * 1.建立可以实现的UDP传输socket服务
 * 2.明确具体的发送的数据
 * 3.通过Socket服务将具体的数据发送出去
 * 4.关闭资源
 * Created by lizhen on 2018/1/29.
 */
public class UDPSocketClient {
    //写代码时,一定要注意try catch的使用,不要讲所有的代码进行try,应为一旦运用异常机制肯定对系统的效率造成一定的影响
    public static void main(String[] args) throws SocketException {

        System.out.println("UDP发送端启动成功了");
        //1.建立可以实现UDP传输的socket服务
        DatagramSocket socket = new DatagramSocket();
        //2.明确具体的发送内容
        String str = "注意啦,UDP发送数据来了!!!!";
        byte[] bytes = str.getBytes();
        //3.通过socket服务将具体的内容发送出去
        try {
            InetAddress byName = InetAddress.getByName("192.168.1.153");
            /**
             * 参数1: 字节数据
             * 参数2:字节长度
             * 参数3.发送的ip地址
             * 参数4.端口号
             */
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, byName, Integer.parseInt("9999"));
            socket.send(datagramPacket);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            socket.close();
        }

    }

}

 

package com.dudu.lizhen.socket.udpsocket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * UDP服务端
 * 思路:
 * 1.创建socket服务,明确一个端口
 * 2.接受数据
 * 3.将其中所需要的数据取出来 ip data
 * 4.关闭资源
 * Created by lizhen on 2018/1/29.
 */
public class UDPSocketServer {
    public static void main(String[] args) throws SocketException {
        //1.创建Socket服务,明确一个端口
        DatagramSocket datagramSocket = new DatagramSocket(Integer.parseInt("9999"));
        //2.定义接受格式
        byte[] buf = new byte[1024];
        DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);

        try {
            //3.接受数据,这是一个阻塞方法
            datagramSocket.receive(datagramPacket);
            //IP地址
            String ip = datagramPacket.getAddress().getHostAddress();
            //端口号
            int port = datagramPacket.getPort();
            //数据
            String str = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
            System.out.println(ip + "-----port:" + port + "-*----" + str);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            datagramSocket.close();
        }

    }
}


2.实现案例:客户端和服务器端实现无线通讯,类似于QQ聊

package com.dudu.lizhen.socket.QQTCPSocket;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

/**
 * TCP协议 客户端
 * Created by lizhen on 2018/1/29.
 */
public class QQTCPSocketClient {
    public static void main(String[] args) throws IOException {
        System.out.println("与服务端聊天中....");
        /**
         * 创建一个连接
         * 参数1:服务器连接ip地址
         * 参数2:服务器端端口号
         */
        Socket socket = new Socket("192.168.1.153", 10003);
        try {
            while (true) {
                //获取socket流中的输出流,将数据发送给服务器端
                OutputStream outputStream = socket.getOutputStream();
                Scanner scanner = new Scanner(System.in);
                String next = scanner.next();
                outputStream.write(next.getBytes());
                System.out.println("我说:" + next);
                InputStream inputStream = socket.getInputStream();
                byte[] bytes = new byte[1024];
                int read = inputStream.read(bytes);
                String str = new String(bytes, 0, read);
                System.out.println("服务端说:" + str);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            socket.close();
        }


    }
}

package com.dudu.lizhen.socket.QQTCPSocket;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * TCP服务端
 * Created by lizhen on 2018/1/29.
 */
public class QQTCPSocketServer {
    public static void main(String[] args) throws IOException {
        System.out.println("与客户聊天中.....");
        //1.创建socket服务器端
        ServerSocket serverSocket = new ServerSocket(10003);
        //2.获取与客户端的连接   是一个阻塞方法
        Socket accept = serverSocket.accept();
        String hostAddress = accept.getInetAddress().getHostAddress();
        System.out.println("客户的ip为:" + hostAddress);
        try {
            while (true) {
                InputStream inputStream = accept.getInputStream();
                byte[] bytes = new byte[1024];
                int read = inputStream.read(bytes);
                String str = new String(bytes, 0, read);
                System.out.println("客户说:" + str);
                OutputStream outputStream = accept.getOutputStream();
                Scanner scanner = new Scanner(System.in);
                String next = scanner.next();
                outputStream.write(next.getBytes());
                System.out.println("我说:" + next);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            accept.close();
            serverSocket.close();
        }


    }
}

我们来看一下效果,客户端与服务端的聊天回话.


案例三:利用浏览器当做客户端,创建一个Socket服务请求本地数据

package com.dudu.lizhen.socket.filesocket;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 通过浏览器访问socket服务端,返回一个文件
 * Created by lizhen on 2018/1/29.
 */
public class FileSocketServer {
    public static void main(String[] args) throws IOException {
        //1.创建Socket服务端
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端已经开始启动");
        FileInputStream fileInputStream = null;

        while (true) {
            //2.与客户端建立连接
            Socket accept = serverSocket.accept();
            System.out.println("服务端已经和客户端建立连接");
            //3.获取本地的test.html
            fileInputStream = new FileInputStream(
                    new File("F:\\baiduwangpan\\JavaWeb入门\\IT蚂蚁余胜军-1、JavaWeb入门\\1-03(手动通过Socket搭建Web服务器)\\test.html")
            );
            OutputStream outputStream = accept.getOutputStream();
            //读取完整数据发送至客户端
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = fileInputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, len);
            }
            fileInputStream.close();
            outputStream.close();
            accept.close();
        }

    }
}
我们看一下效果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值