四步帮你搞定网络编程之第二步

目录

一:基础知识点

1.1 源IP地址和目的IP地址

 1.2 源端口号和目的端口号

1.3 端口号和进程id

1.4 认识tcp和udp协议

二:socket编程接口

2.1 socket 常见API

2.2 简单的UDP网络程序

2.2.1 udp服务端

 三:简单的TCP网络程序

3.1 TCP socket API 详解

3.2 socket类

3.3 Tcp通用服务器

3.4 Tcp客户端

 3.5 英译汉服务器

                            总结


一:基础知识点

 

1.1 IP地址和目的IP地址

 IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址

 1.2 源端口号和目的端口号

传输层协议 (TCP UDP) 的数据段中有两个端口号 , 分别叫做源端口号和目的端口号 . 就是在描述 " 数据是谁发的 , 要发 给谁";

1.3 端口号和进程id

我们的端口号是唯一表示一个进程。另外 , 一个进程可以绑定多个端口号 ; 但是一个端口号不能被多个进程绑定。

1.4 认识tcp和udp协议

这个建议大家翻看我前面写的文章,就不一 一赘述了。

二:socket编程接口

2.1 socket 常见API

见下表:

四步帮你搞定网络编程之第二步_第1张图片

2.2 简单的UDP网络程序

实现一个简单的服务端接收客户端输入的信息然后在服务端显示。

2.2.1 udp服务端

import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket; 
import java.net.InetAddress;
 import java.util.Scanner;
public class UdpClient { 
// 定义发送数据报的目的地
 public static final int DEST_PORT = 30000; 
public static final String DEST_IP = "127.0.0.1";
 // 定义每个数据报的最大大小为4K 
private static final int DATA_LEN = 4096;
 // 定义接收网络数据的字节数组 
byte[] inBuff = new byte[DATA_LEN];
 // 创建接受回复数据的DatagramPacket对象
private DatagramPacket packet_in = new DatagramPacket(inBuff, inBuff.length); 
// 定义一个用于发送的DatagramPacket对象
 private DatagramPacket packet_out = null;
 public void start() throws IOException { try (DatagramSocket socket = new DatagramSocket()) { // 初始化发送用的DatagramSocket InetAddress ip = InetAddress.getByName(DEST_IP); packet_out = new DatagramPacket(new byte[0], 0, ip, DEST_PORT); // 创建键盘输入流 Scanner sc = new Scanner(System.in); System.out.println("请输入数据"); // 不断读取键盘输入 String key =null; // 键盘输入字符对应的byte数组 byte[] keyBuff = null; while (sc.hasNextLine()) { key = sc.nextLine();
比特科技
客户端启动后显示如下:
客户端输入数据后,客户端和服务端显示如下:
实现英译汉服务器
通过上面的UDP服务端进行修改就可以实现英汉互译的服务器,服务端代码需要调整,客户端则不变,代码如下:
if ("exit".equals(key)) { break; }// 输入的字符串→字节数组 keyBuff = key.getBytes(); // 设置发送用的DatagramPacket里的字节数据 packet_out.setData(keyBuff); // 发送数据报 socket.send(packet_out); // 读取Socket中的数据,读到的数据放在inPacket所封装的字节数组里。 socket.receive(packet_in); System.out.println(new String(inBuff, 0, packet_in.getLength())); System.out.println("请输入数据:"); }System.out.println("=== 客户端退出 ==="); } }public static void main(String[] args) throws IOException { new UdpClient().start(); } }

客户端启动后显示如下: 

客户端输入数据后,客户端和服务端显示如下: 

四步帮你搞定网络编程之第二步_第2张图片 

2.2.2实现英译汉服务器

通过上面的UDP服务端进行修改就可以实现英汉互译的服务器,服务端代码需要调整,客户端则不变,代码如下:

package com.store.frank.udp; 
import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.SocketAddress;
import java.util.HashMap;
 import java.util.Map;
public class UdpDictServer {
public static void main(String[] args) throws Exception {
new UdpDictServer().start();
}
// 定义udp端口号
public static final int PORT = 30000;
// 每个数据报最大为4K
private static final int DATA_LEN = 4096;
// 接收网络数据的字节数组
byte[] buff_in = new byte[DATA_LEN];
// 以指定字节数组创建准备接受数据的DatagramPacket对象
private DatagramPacket packet_in = new DatagramPacket(buff_in, buff_in.length);
// 定义一个用于发送的DatagramPacket对象
private DatagramPacket packet_out;
public void start() throws Exception {
try(DatagramSocket socket = new DatagramSocket(PORT)){
String key = null; // 客户端输入的英文单词
String value=null; // 服务端翻译的中文内容
SocketAddress address=null; // 获取客户端对象,通过该对象将数据写给对方,否则没有目的地
byte[] reviceData=null; // 返回给客户端的数据
System.out.println("英译汉服务器启动了......");
while (true){
// 读取socket中的数据,然后将数据封装到 packet_in 中
socket.receive(packet_in);
// 获取客户端输入的数据
buff_in=packet_in.getData();
// 将byte数组转换为字符串 需要去掉后面的空格
key=new String(buff_in,0,buff_in.length).trim();
// 根据map的key获取value
value=maps.get(key);
if(null == value){
value="默认值";
}
address=packet_in.getSocketAddress();
// 检查退出条件
if("down".equals(key)){
System.out.println("客户端输入的是:"+key);
reviceData="服务器关闭了,请重试".getBytes();
packet_out=new DatagramPacket(reviceData,reviceData.length,address);客户端输入数据后,客户端和服务端显示如下:
2.2简单的TCP网络程序
和刚才UDP类似. 实现一个简单的英译汉的功能
TCP socket API 详解
ServerSocket类
socket.send(packet_out);
break;
}else {
System.out.println("客户端输入的是:"+key+",翻译后的结果是"+value);
// 构建服务端发送给客户端的数据
reviceData=("你输入的英文单词翻译成中文是:"+value).getBytes();
// 构建 packet_out 发送数据
packet_out=new DatagramPacket(reviceData,reviceData.length,address);
socket.send(packet_out);
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("=====服务器关闭=====");
}
}
// 定义map集合,用来存放需要翻译的单词。
private static Map maps = new HashMap<>();
// 向map中添加数据
static {
maps.put("dog", "狗");
maps.put("cat", "猫");
maps.put("fish", "鱼");
maps.put("bird", "鸟");
maps.put("pig", "猪");
}
}

 客户端输入数据后,客户端和服务端显示如下:

四步帮你搞定网络编程之第二步_第3张图片

 三:简单的TCP网络程序

3.1 TCP socket API 详解

和刚才 UDP 类似 . 实现一个简单的英译汉的功能
TCP socket API 详解
ServerSocket
四步帮你搞定网络编程之第二步_第4张图片

 bind():

服务器程序所监听的网络地址和端口号通常是固定不变的 , 客户端程序得知服务器程序的地址和端口号后
就可以向服务器发起连接 ; 服务器需要调用 bind 绑定一个固定的网络地址和端口号 ;
如果地址为 null ,则系统将接收临时端口和有效的本地地址来绑定套接字。
accept():
三次握手完成后 , 服务器调用 accept() 接受连接 ;
如果服务器调用 accept() 时还没有客户端的连接请求 , 就阻塞等待直到有客户端连接上来 ;
Socket 是一个返回值 , 代表网络的套接字 ;

3.2 socket类

具体如下:

四步帮你搞定网络编程之第二步_第5张图片 

3.3 Tcp通用服务器

TCP 服务端,接收客户端内容,然后输出:
package com.store.frank.http;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpServer {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8888);
        System.out.println("服务器启动了....");
        boolean isShow=true; // 设置第一次输出[服务器启动了....],启动后不再显示。
        while (true){
            try {
                Socket client = server.accept();
                String clientName=client.getInetAddress().getLocalHost().toString();
                if(isShow){
                    System.out.println("客户端:"+clientName+"已连接到服务器");
                }
                isShow=false;
                BufferedReader br = new BufferedReader(new
                        InputStreamReader(client.getInputStream()));
                String word = br.readLine(); // word 客户端发送来的消息
                if(null != word){
                    System.out.println("客户端输入的是:"+word+",服务器响应的是:"+word);
                    BufferedWriter bw = new BufferedWriter(new
                            OutputStreamWriter(client.getOutputStream()));
                    bw.write(word+"\n");
                    bw.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.4 Tcp客户端

package com.store.frank.http;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;import java.net.Socket;
import java.util.Scanner;
public class HttpClient {
    public static void main(String[] args) {
        try {
            Socket s = new Socket("127.0.0.1",8888);
//构建IO
            InputStream is = s.getInputStream();
            OutputStream os = s.getOutputStream();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            Scanner scanner=new Scanner(System.in);
            String key = null;
            String value = null;
            while (true){
                System.out.println("请输入数据");
                if(scanner.hasNext()) {
                    key = scanner.nextLine();
//向服务器端发送一条消息
                    bw.write(key+"\n");
                    bw.flush();
//读取服务器返回的消息
                    value = br.readLine();
                    System.out.println("客户端输入的是:"+key+",服务器响应的是:"+value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
服务端与客户端启动后,客户端输入 cat 后,客户端和服务端显示如下:
四步帮你搞定网络编程之第二步_第6张图片

 3.5 英译汉服务器

具体代码如下:

package com.store.frank.http;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
public class HttpDictServer {
// 定义map集合,用来存放需要翻译的单词。
private static Map maps = new HashMap<>();
// 向map中添加数据
static {
maps.put("dog", "狗");
maps.put("cat", "猫");
maps.put("fish", "鱼");
maps.put("bird", "鸟");
maps.put("pig", "猪");
}
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8888);
System.out.println("服务器启动了....");
boolean isShow=true; // 设置第一次输出[服务器启动了....],启动后不再显示。
while (true){
try {
Socket client = server.accept();
String clientName=client.getInetAddress().getLocalHost().toString();
if(isShow){
System.out.println("客户端:"+clientName+"已连接到服务器");
}
isShow=false;
BufferedReader br = new BufferedReader(new
InputStreamReader(client.getInputStream()));
// key 客户端发送来的消息
String key = br.readLine();
// 服务器翻译后的结果
String value=maps.get(key);if(null != key){
if(null == value){
value="default";
System.out.println("客户端输入的是:"+key+",服务端返回的是默认值:default");
BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(client.getOutputStream()));
bw.write(value+"\n");
bw.flush();
}else{
System.out.println("客户端输入的是:"+key+",服务器翻译后是:"+value);
BufferedWriter bw = new BufferedWriter(new
OutputStreamWriter(client.getOutputStream()));
bw.write(value+"\n");
bw.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
英译汉的客户端与通用服务器的客户端代码是相同的。
服务端与客户端启动后,客户端输入 cat 后,客户端和服务端显示如下:
四步帮你搞定网络编程之第二步_第7张图片

                            总结

 

  以上是今天分享的内容,如有不当之处请大家多多指教,感激不尽!

你可能感兴趣的:(Java基础,网络,java,ide)