欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SOCKET

程序员文章站 2022-07-11 10:37:45
...

Socket是什么

建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

socket是套接字,TCP/IP网络的API。(港口码头/车站)Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。

TCP/IP协议族包括运输层、网络层、链路层,而socket所在位置如图,Socket是应用层与TCP/IP协议族通信的中间软件抽象层。

                                         SOCKET

说白了Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

连接过程

根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。

  • (1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
  • (2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
  • (3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

基本的SOCKET接口函数

                                         SOCKET

服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。


客户端向服务器端发送连接请求后,就被动地等待服务器的响应。

典型的TCP客户端要经过下面三步操作:

  • 1、创建一个Socket实例:构造函数向指定的远程主机和端口建立一个TCP连接;
  • 2、通过套接字的I/O流与服务端通信;
  • 3、使用Socket类的close方法关闭连接。

服务端的工作是建立一个通信终端,并被动地等待客户端的连接。
典型的TCP服务端执行如下两步操作:
1、创建一个ServerSocket实例并指定本地端口,用来监听客户端在该端口发送的TCP连接请求;
2、重复执行:

  •        1)调用ServerSocket的accept()方法以获取客户端连接,并通过其返回值创建一个Socket实例;
  •        2)为返回的Socket实例开启新的线程,并使用返回的Socket实例的I/O流与客户端通信;
  •        3)通信完成后,使用Socket类的close()方法关闭该客户端的套接字连接。

socket是java.net包下的类,

Sockets:使用 TCP 协议实现网络通信;

TCP    客户端个服务端


Socket和ServerScoket,建立客户端和服务端,建立连接后通过socket的IO流进行数据传输。
通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机。
tcp连接:
客户端:创建socket服务(Socket),并指定要连接的主机和端口。
服务端:1创建socket服务(ServerSocket)
              2获取连接过来的客户端对象accept方法(阻塞式),
              3客户端如果发来数据,服务端要使用对应的客户端对象,并获取对象的读取流读取数据。

public class TcpClient {//客户端
    public static void main(String[] args) {
        try {//1创建客户端的soclet服务,指定目的主机和端口
            Socket s= new Socket("192.168.1.107",10003);
            //2获取socket流中的输出流,3关闭
            OutputStream out=s.getOutputStream();
            out.write("tcpSabber".getBytes());
            s.close();
        } catch (Exception e) {e.printStackTrace(); }
    }
}
public class TcpServer {//服务器端
    public static void main(String[] args) {
        try {
            //建立服务器端socket服务,并监听一个端口
            ServerSocket ss=new ServerSocket(10003);
            //通过accept方法获取连接过来的客户端对象
            Socket s=ss.accept();
            String ip=s.getInetAddress().getHostAddress();
            System.out.println(ip+"....connected");
            //获取客户端发送过来的数据,使用客户端读取流读取
            InputStream in=s.getInputStream();
            byte[] buf=new byte[1024];
            int len=in.read(buf);
            System.out.println(new String(buf,0,len));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package com.haibo.MySocket;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * Created with IDEA.
 * User:haibo.
 * DATE:2018/6/22/022
 *演示tcp的传输的客户端和服务端的互访。
 *需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。
*/
 public class TcpDemo2 {
    /*
    客户端:
    1,建立socket服务。指定要连接主机和端口。
    2,获取socket流中的输出流。将数据写到该流中。通过网络发送给服务端。
    3,获取socket流中的输入流,将服务端反馈的数据获取到,并打印。
    4,关闭客户端资源。
    */
        public static void main(String[] args)throws Exception {
            Socket s = new Socket("192.168.1.254",10004);
            OutputStream out = s.getOutputStream();
            out.write("服务端,你好".getBytes());
            InputStream in = s.getInputStream();
            byte[] buf = new byte[1024];
            int len = in.read(buf);
            System.out.println(new String(buf,0,len));
            s.close();
        }
    }
 
package com.haibo.MySocket;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * Created with IDEA.
 * User:haibo.
 * DATE:2018/6/22/022
 */
public class TcpDemo2Serv {
    public static void main(String[] args) throws Exception
    {
        ServerSocket ss = new ServerSocket(10004);
        Socket s = ss.accept();
        String ip = s.getInetAddress().getHostAddress();
        System.out.println(ip+"....connected");
        InputStream in = s.getInputStream();
        byte[] buf = new byte[1024];
        int len = in.read(buf);
        System.out.println(new String(buf,0,len));
        OutputStream out = s.getOutputStream();
        Thread.sleep(10000);
        out.write("哥们收到,你也好".getBytes());
        s.close();
        ss.close();
    }
}
 

一:udp  发送端和接收端

DatagramSocket类用来发送和接收数据报包的套接字。无连接包投递。

1通过udp方式将一段文字数据发送出去(建立udpscoket服务,提供数据,并将数据封装到数据包中,通过socket服务发送功能将数据包发出去,关闭资源)

public class UdpSend {//发送
    public static void main(String[] args) {
        try {//1通过udp服务,通过DatagramSocket对象。
            DatagramSocket ds=new DatagramSocket();
            //2确定数据,并封装成数据包
            byte[] buf ="send Sabber".getBytes();
            DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.107"),10000);
            //3.通过socket服务,将已有的数据包发送出去。
            ds.send(dp);
            //4.关闭
        } catch (Exception e) {}
    }
}
public class UdpRece {//接收
    public static void main(String[] args) {
        try {//1.创建udpsocket服务,建立端点.监听一个接口
            DatagramSocket ds=new DatagramSocket(10000);
            //2.定义一个数据包存储接收到的字节数据。
            while(true){
            byte[] buf=new byte[1024];
            DatagramPacket dp=new DatagramPacket(buf,buf.length);
            //3.通过socket服务的receive方法将收到的数据出存入已定义好的数据包
            ds.receive(dp);
            //4.通过数据包对象的特有功能将不同的数据取出,打印到控制台
            String ip=dp.getAddress().getHostAddress();
            String data= new String(dp.getData(),0,dp.getLength());
            int port=dp.getPort();
            System.out.print(ip+data+port);
            }
            //5.关闭资源
           // ds.close();
        } catch (Exception e) {
            e.printStackTrace();}
    }
}

编写一个聊天程序:多线程技术,一个线程控制收一个控制发,

class UdpCart {
        public static void main(String[] args) throws Exception {
            DatagramSocket sendSocket = new DatagramSocket();
            DatagramSocket receSocket = new DatagramSocket(10002);
            new Thread(new Send(sendSocket)).start();
            new Thread(new Rece(receSocket)).start();
        }
    static class Send implements Runnable {
        private DatagramSocket ds;
        public Send(DatagramSocket ds) {
            this.ds = ds;
        }
        public void run() {
            try {
                BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
                String line = null;
                while((line=bufr.readLine())!=null) {
                    byte[] buf = line.getBytes();
                    DatagramPacket dp =
                            new DatagramPacket(buf,buf.length, InetAddress.getByName("192.168.1.255"),10002);
                    ds.send(dp);
                    if("886".equals(line))
                        break;
                }
            }
            catch (Exception e) {
                throw new RuntimeException("发送端失败");
            }
        }
    }
    static class Rece implements Runnable {
        private DatagramSocket ds;
        public Rece(DatagramSocket ds) {
            this.ds = ds; }
        public void run() {
            try
            {
                while(true) {
                    byte[] buf = new byte[1024];
                    DatagramPacket dp = new DatagramPacket(buf,buf.length);
                    ds.receive(dp);
                    String ip = dp.getAddress().getHostAddress();
                    String data = new String(dp.getData(),0,dp.getLength());if("886".equals(data))
                    {
                        System.out.println(ip+"....离开聊天室");
                        break;
                    }
                    System.out.println(ip+":"+data);
                }
            }
            catch (Exception e) {
                throw new RuntimeException("接收端失败");
            }
        }
    }}

原文来源:

https://blog.csdn.net/lettyisme/article/details/80773987