目录
一:基础知识点
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 英译汉服务器
总结
在IP数据包头部中, 有两个IP地址, 分别叫做源IP地址, 和目的IP地址
这个建议大家翻看我前面写的文章,就不一 一赘述了。
见下表:
实现一个简单的服务端接收客户端输入的信息然后在服务端显示。
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实现英译汉服务器
通过上面的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", "猪"); } }
客户端输入数据后,客户端和服务端显示如下:
bind():
具体如下:
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();
}
}
}
}
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();
}
}
}
具体代码如下:
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();
}
}
}
}
以上是今天分享的内容,如有不当之处请大家多多指教,感激不尽!