网络编程套接字

预备知识:
1. 源IP地址和目的IP地址

在IP数据包头部中,有两个IP地址,分别叫做源IP地址和目的IP地址。只能将数据发送到对方的机器上并不能区分是哪个程序。

2. 端口号

端口号(port)是传输层协议的内容

  • 是一个32位的整数
  • 用来表示一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理
  • IP+端口号,标识网络上的唯一一台机器上的唯一进程
  • 一个端口号只能被一个进程占用
    注意:一个进程可以绑定多个端口号,但是一个端口号不能被多个进程绑定。
3. TCP协议(传输控制协议)
  • 传输层协议
  • 有连接(面向连接)
  • 可靠传输
  • 面向字节流
4. UDP协议(用户数据报协议)
  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报
5.socket编程接口
  • DatagramSocket类的常用方法:

1.DatagramSocket(int port,InetAddress laddr)
创建一个数据报套接字,绑定到指定的本地地址
2.DatagrsmSocket(SocketAddress bindaddr)
创建一个数据报套接字,绑定到指定的本地套接字地址
3.void bind(SocketAddress addr)
将此DatagramSocket绑定到待定的地址和端口
4.void connect(InetAddress address,int port)
将套接字连接到此套接字的远程地址
5.void receive(DatagramPacket p)
从此套接字接收数据包
6.void close()
关闭此数据报套接字
7.void send(DatagramPacket p)
从此套接字发送数据报包

  • 对Socket的简单理解:内核和用户程序直接进行网络数据交互的接口。绑定了一组五元组。
基于udp协议实现客户端和服务器的代码演示

服务器

package udp.echo;

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

public class Server1226 {
    public static void main(String[] args) throws IOException {
        //1.新建一个DatagramSocket
        DatagramSocket udpServerSocket=new DatagramSocket(9898);
        byte[] receiveBuffer=new byte[1024];
        DatagramPacket receivePacket=new DatagramPacket(receiveBuffer,receiveBuffer.length);
        //2.等着客户端来撩
        udpServerSocket.receive(receivePacket);
       InetAddress clientAddress= receivePacket.getAddress();
        System.out.printf("我从%s:%d 收到了消息%n",clientAddress.getHostAddress(),receivePacket.getPort());
        System.out.printf("我一共收到了%d字节的数据%n",receivePacket.getLength());
        //字节转字符
        String message=new String (receivePacket.getData(),
                0,
                receivePacket.getLength(),
                "UTF-8");
        System.out.println(message);
        udpServerSocket.close();
    }
}

客户端

package udp.echo;

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

public class Client1226 {
    public static void main(String[] args) throws IOException {
        DatagramSocket udpClientSocket=new DatagramSocket();
        String message="收到我的消息没?";
        byte[] senBuffer=message.getBytes("UTF-8");
        byte[] serverIP=new byte[4];
        serverIP[0]=127;
        serverIP[1]=0;
        serverIP[2]=0;
        serverIP[3]=1;
        InetAddress serverAddress=InetAddress.getByAddress(serverIP);
        DatagramPacket sendPacket=new DatagramPacket(senBuffer,senBuffer.length,serverAddress,9898);
        udpClientSocket.send(sendPacket);
        udpClientSocket.close();
    }
}

运行结果

在这里插入图片描述

基于tcp协议实现客户端和服务器的代码演示

服务器

package tcp.http;

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

public class Server1226 {
    public static void main(String[] args) throws IOException {
        //监听8080端口
        ServerSocket tcpServerSocket=new ServerSocket(8080);
        while(true){
            Socket clientSocket=tcpServerSocket.accept();
           InetAddress clientAddress= clientSocket.getInetAddress();
           int clientPort=clientSocket.getPort();
            System.out.printf("有客户端连接上来 %s:%d%n",clientAddress.getHostAddress(),clientPort);
            //获取字节流
           InputStream is= clientSocket.getInputStream();
            //字节流转换为字符流
            InputStreamReader isReader=new InputStreamReader(is,"UTF-8");
            //字符流转换为缓冲字符流
            BufferedReader reader=new BufferedReader(isReader);
            //获取输出字节流
            OutputStream os=clientSocket.getOutputStream();
            PrintStream out=new PrintStream(os,true,"UTF-8");
            String line;
            while((line=reader.readLine())!=null) {
                System.out.println(line);
                out.println("我已经收到了你的消息");
            }
        }
    }
}

服务端运行结果
在这里插入图片描述
客户端

package tcp.http;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.*;

public class Client1226 {
    public static void main(String[] args) throws IOException {
        Socket tcpClientSocket=new Socket();
        byte[] ipv4={127,0,0,1};
        InetAddress serverAddress=InetAddress.getByAddress(ipv4);
        SocketAddress serverSocketAddress= new InetSocketAddress(serverAddress,8080);
        tcpClientSocket.connect(serverSocketAddress);
       //通过字节流直接写入请求
        OutputStream os=tcpClientSocket.getOutputStream();
        os.write("我是好人\r\n".getBytes("UTF-8"));
        //通过字节流,直接读取数据
        InputStream is=tcpClientSocket.getInputStream();
        byte[]  buffer=new byte[1024];
        int len=is.read(buffer);
        String response=new String (buffer,0,len,"UTF-8");
        System.out.println(response);
        tcpClientSocket.close();
    }
}

客户端运行结果
在这里插入图片描述
总结

  • UDP是面向报文的,例如发送端发送的是"hello world",接收端接收到的一定是"hello world".
  • TCP是面向流的,发送端可能不是一次发送完成,接收端读到\r\n才认为读取完毕。例如发送端发送的是"hello world",接收端可能接收的是"h",“ello”,“wor”,“ld”.
  • TCP是面向连接的,用 connect连接
    UDP是无连接的,没有调用过connect
  • UDP是不可靠的,发送后对方是否收到,不知道
    TCP是可靠的,发送后对方一定是能收到的,如果收不到,也知道出了问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值