接触网络编程首先需要了解网络分层:

1 scoket:TCP编程 中 Socket 是一个抽象概念,一个应用程序通过一个 Socket 来建立一个远程连接,而 Socket 内部通过 TCP/IP 协 议把数据传输到网络。

使用 Socket 进行网络编程时,本质上就是两个进程之间的网络通信。其中一个进程必须充当服务器端,它会主动监听某个指定 的端口,另一个进程必须充当客户端,它必须主动连接服务器的 IP 地址和指定端口,如果连接成功,服务器端和客户端就成功地建 立了一个 TCP 连接,双方后续就可以随时发送和接收数据。 因此,当 Socket 连接成功地在服务器端和客户端之间建立后:

对服务器端来说,它的 Socket 是指定的 IP 地址和指定的端口号;

对客户端来说,它的 Socket 是它所在计算机的 IP 地址和一个由操作系统分配的随机端口号。

TCP:

服务器端:要使用 Socket 编程,我们首先要编写服务器端程序。 Java 标准库提供了 ServerSocket 来实现对指定 IP 和指定端口的监听。 ServerSocke t 的典型实现代码如下:

package liuzhen06;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;public class woker05 {public static void main(String[] args) {//服务端List<String> lister = new ArrayList<String>();lister.add("齐天大圣");lister.add("二郎真君");lister.add("菩提祖师");lister.add("三太子");lister.add("如来佛祖");lister.add("金蝉子");lister.add("六耳猕猴");lister.add("持国天王");lister.add("万妖之祖");lister.add("原始天尊");lister.add("上古真龙");//System.out.println(lister.get(1));try(ServerSocket servor =  new ServerSocket(9999)){while(true) {//接受用户端链接Socket sock = servor.accept();//获取用户端IP地址String ipString = sock.getInetAddress().getHostAddress();//获取该用户的幸运数字try(BufferedReader buf = new BufferedReader( new InputStreamReader(sock.getInputStream()));BufferedWriter bos = new BufferedWriter( new OutputStreamWriter( sock.getOutputStream()));){bos.write("请输入你的幸运数字");//获取用户幸运数字Integer i = Integer.parseInt(buf.readLine());System.out.println("服务器来自游戏用户端"+sock+"幸运数字"+i);//获取用户转生人物int a =(int)(Math.random()*10)+i;    if(a>=10) {a=(int)(Math.random()*11);}String result = lister.get(a);//配送身份bos.write("您转生的西游对象为:"+result);bos.flush();}}         }catch (IOException e) {e.printStackTrace();}}
}

客户端

package liuzhen06;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;public class worke03 {//客户端public static void main(String[] args) {Scanner input = new Scanner(System.in);while(true) {try (Socket cltenr = new Socket("192.168.254.153",8888)) {//获取控制台的控制的输出(问题)BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(cltenr.getOutputStream()));BufferedReader read = new BufferedReader(new InputStreamReader(cltenr.getInputStream()));{//获取控制台String question = input.nextLine();if(question.equals("over")) {break;//}//发送问题至服务器writer.write(question);writer.flush();//暂时结束本次输出cltenr.shutdownOutput(); //获取来自服务区的答案String answer = read.readLine();System.out.println("你的转生对象为: "+ answer);} } catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}  System.out.println("资质逆天!!!!");
}
}

Socket流:Socket 连接创建成功后,无论是服务器端,还是客户端,我们都使用 Socket 实例进行网络通信。因为 TCP 是一种基于流 的协议,因此, Java 标准库使用 InputStream 和 OutputStream 来封装 Socket 的数据流,这样我们使用 Socket 的流,和普通 IO 流类似。

// 用于读取网络数据:
InputStream in = sock.getInputStream();// 用于写入网络数据:
OutputStream out = sock.getOutputStream();

写入网络数据时,必须要调用 flush() 方法。如果不调用 flush() ,我们很可能会发现,客户端和服务器都收不到数据,这并不是 Java 标准库的设计问题,而是我们以流的形式写入数据的时候,并不是一写入就立刻发送到网络,而是先写入内存缓冲区,直到缓 冲区满了以后,才会一次性真正发送到网络,这样设计的目的是为了提高传输效率。如果缓冲区的数据很少,而我们又想强制把这些 数据发送到网络,就必须调用 flush() 强制把缓冲区数据发送出去。

小结:

  1. 使用Java进行TCP编程时,需要使用 Socket 模型: 服务器端用 ServerSocket 监听指定端口;
  2. 客户端使用 Socket(InetAddress, port) 连接服务器;
  3. 服务器端用 accept() 接收连接并返回 Socket 实例;
  4. 双方通过 Socket 打开 InputStream / OutputStream 读写数据;
  5. 服务器端通常使用多线程同时处理多个客户端连接,利用线程池可大幅提升效率;
  6. flush() 方法用于强制输出缓冲区到网络。

UDP:

和 TCP 编程相比, UDP 编程就简单得多,因为 UDP 没有创建连接,数据包也是一次收发一个,所以没有流的概念。 在 Java 中使用 UDP 编程,仍然需要使用 Socket ,因为应用程序在使用 UDP 时必须指定网络接口( IP地址 )和端口号。 注意: UDP 端口和 TCP 端口虽然都使用 0 ~ 65535 ,但他们是两套独立的端口,即一个应用程序用TCP占用了端口 126664 ,不影 响另一个应用程序用UDP占用端口 126664。

服务器端:

  1. 在服务器端,使用 UDP 也需要监听指定的端口。Java提供了 DatagramSocket 来实现这个功能

    DatagramSocket ds = new DatagramSocket(6666);
  2. 如果没有其他应用程序占据这个端口,那么监听成功,我们就使用一个无限循环来处理收到的 UDP 数据包
    while (true) { // 无限循环}
  3. 要接收一个 UDP 数据包,需要准备一个 byte[] 缓冲区,并通过 DatagramPacket 实现接收
    byte[] buffer = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    ds.receive(packet);
  4. 假设我们收取到的是一个 String ,那么,通过 DatagramPacket 返回的 packet.getOffset() 和 packet.getLength() 确定数据 在缓冲区的起止位置
    String s = new String(packet.getData(), packet.getOffset(), packet.getLength(), StandardCharsets.UTF_8);
  5. 当服务器收到一个 DatagramPacket 后,通常必须立刻回复一个或多个 UDP 包,因为客户端地址在 DatagramPacket 中,每 次收到的 DatagramPacket 可能是不同的客户端,如果不回复,客户端就收不到任何 UDP 包。 发送 UDP 包也是通过 DatagramPacket 实现的
    byte[] data = ...
    packet.setData(data);
    ds.send(packet);

总代码:

package liuzhen07;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;public class woker02 {
public static void main(String[] args) {//服务端Map<String, String> map = new HashMap<String, String>(){{put("one","齐天大圣");put("two","齐天二圣");put("three","齐天三圣");put("four","齐天五圣");put("five","齐天六圣");}};try (  //监听客户端DatagramSocket serverSocket = new DatagramSocket(7788)) {    while (true) { byte[] buffer = new byte[1024];//准备空数据包DatagramPacket packet = new DatagramPacket(buffer, buffer.length);// 接受一个UDP数据包serverSocket.receive(packet); //等待接受// 收取到的数据存储在buffer中,由(int 类型)packet.getOffset(), packet.getLength()指定起始位置和长度// 将其按UTF-8编码转换为String:String s = new String(packet.getData(), packet.getOffset(), packet.getLength());System.out.println("来自客户端"+s);//根据客户端内容匹配集合元素String worker  = map.get(s);if(worker==null) {worker ="超出认知理解";         }// 发送数据:byte[] data = worker.getBytes();//封装成datagramPacket数据包;packet.setData(data);//重复设计内容serverSocket.send(packet);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}
}
}

客户端:

1.客户端打开一个 DatagramSocket 使用以下代码:

DatagramSocket ds = new DatagramSocket();
ds.setSoTimeout(1000);
ds.connect(InetAddress.getByName("localhost"), 6666);

客户端大概实现:

package liuzhen07;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;public class woker01 {//客户端public static void main(String[] args) {try (//创建基于UDP协议的DatagramSocket对象DatagramSocket socket = new DatagramSocket()) {//timeout超时socket.setSoTimeout(200000);//链接服务器(IP端口)socket.connect(new InetSocketAddress("192.168.198.184",7788));//发送String word  = "one";byte [] wordbuff = word.getBytes();//获取英文单词字符串的字节数组//封装成DatagramSocket数据包DatagramPacket packet = new DatagramPacket(wordbuff, wordbuff.length);//发送数据包socket.send(packet);//接受数据byte[] buffer = new byte[1024];packet = new DatagramPacket(buffer, buffer.length);socket.receive(packet);String resp = new String(packet.getData(), packet.getOffset(), packet.getLength());System.out.println(resp);socket.disconnect();//关闭socket} catch (IOException e) {e.printStackTrace();}}}

小结

  1. 使用 UDP 协议通信时,服务器和客户端双方无需建立连接;
  2. 服务器端用 DatagramSocket(port) 监听端口;
  3. 客户端使用 DatagramSocket.connect() 指定远程地址和端口;
  4. 双方通过 receive() 和 send() 读写数据;
  5. DatagramSocket 没有 IO 流接口,数据被直接写入 byte[] 缓冲区;

网络编程UDP与TCP相关推荐

  1. Linux Socket网络编程UDP、TCP 阻塞与非阻塞 断线重连机制

    三种非阻塞模式的方法: (1) fcntl函数 int Mode = fcntl(sockfd, F_GETFL, 0);       //获取文件的Mode值     fcntl(sockfd, F ...

  2. 关于JAVA网络编程UDP和TCP(上)

    对于JAVA的网络编程我们又称之为socket编程.首先,网络编程,顾名思义,要涉及到网络,其中网络协议是必不可少的对于我们而言,一个重要的网络协议是大家要会的:TCP/IP协议,udp协议. 一.网 ...

  3. Linux网络编程-UDP和TCP协议详解

    1|0一. 引言 网络协议是每个程序员都要掌握的基础知识,干啥都离不开网络,就算在家里新买了个路由器不是吗,同事连不上网,你的女朋友手机没有网看剧了正看到高潮部分,到那时候你打开百度......那嫌弃 ...

  4. 网络编程——TCP网络编程UDP编程

    1.计算机网络:将分布在不同区域不同地方的多台计算机和网络设备通过线程连接起来组成一套大型系统,来实现计算机之间的信息传递和资源共享的设备. 2.网络编程:编写一个程序来实现网络间信息传递. 网络编程 ...

  5. 【Linux】网络编程三:TCP通信和UDP通信介绍及代码编写

    参考连接:https://www.nowcoder.com/study/live/504/2/16. [Linux]网络编程一:网络结构模式.MAC/IP/端口.网络模型.协议及网络通信过程简单介绍 ...

  6. 迈入JavaWeb第一步,Java网络编程基础,TCP网络编程URL网络编程等

    文章目录 网络编程概述 网络通信要素 要素一IP和端口号 要素二网络协议 TCP网络编程 UDP网络编程 URL网络编程 Java网络编程基础 网络编程概述 Java是Internet上的语言,它从语 ...

  7. TCP/IP网络编程之基于TCP的服务端/客户端(一)

    TCP/IP网络编程之基于TCP的服务端/客户端(一) 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于 ...

  8. java网络编程socket\server\TCP笔记(转)

    java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04|  分类: Socket |  标签:java  |举报|字号 订阅 1 TCP的开销 a  连接 ...

  9. java网络编程,通过TCP,Socket实现多对一的局域网聊天室

    java网络编程,通过TCP,Socket实现多对一的局域网聊天室 可以实现多个客户端连接服务器,服务器接收到信息就会把信息广播到所有的客户端 这是服务器端的代码 View Code import j ...

  10. Linux网络编程---详解TCP

    Linux网络编程---详解TCP的三次握手和四次挥手_shanghx_123的博客-CSDN博客_tcp的协议数据单元被称为 TCP协议详解(TCP报文.三次握手.四次挥手.TIME_WAIT状态. ...

最新文章

  1. Flink在美团的应用与实践听课笔记
  2. 十条nmap常用的扫描命令
  3. 条件变量实现线程同步
  4. 输入一个十进制数,转化为二进制
  5. iPhone 13系列7款新机已通过EEC认证:或继续9月亮相
  6. linux温故知新十
  7. JVM(2)--OutOfMemoryError实战
  8. mysql5.6 主从同步
  9. WCF编程系列(七)信道及信道工厂
  10. 微信小程序构建新闻列表
  11. html中图片集合,HTML标签大集合
  12. hash函数的基本知识
  13. oracle plsql 绑定变量值,dbms_sqltune解析SQL的BIND_DATA绑定变量值
  14. 字符串分割、切片、替换、去除头尾指定字符
  15. JavaBeans分类
  16. Apple苹果产品MFi设计及标准汇总
  17. Android 切换全屏,取消全屏
  18. Freeswitch Event Socket IVR外呼方案
  19. 深度相机(四)--Realsense概览
  20. 【Spring6】| Bean的生命周期(五步、七步、十步法剖析)

热门文章

  1. python输入单词显示长度_Python按长度打印单词
  2. Windows10系统迁移-同一PC硬盘之间
  3. 人类为什么不会被人工智能取代?
  4. python的spider如何让鼠标不_python wooyun爬虫模拟鼠标等
  5. 淘宝网卖家必须缴纳消保保证金才能发布宝贝的商品类目
  6. 淘宝发布宝贝提示“您的消保保证金额度不足,已启动到期保障”
  7. 腾讯地图基于 WebGL实现自定义栅格图层踩坑实录
  8. 摄影曝光口诀_摄影中的“向右曝光”是什么以及为什么要这么做
  9. Nacos 配置中心作用以及使用
  10. Mac 上设置锁屏快捷键