本文知识点(目录):
1、概述
1、在java中网络通讯作为Socket(插座)通讯,要求两台都必须安装socket.
2、不同的协议就会有不同的插座(Socket)
2、UDP通讯协议
2.1、UDP通讯协议的特点
1.将数据封装为数据包,面向无连接
2.每个数据包大小限制为64kb中
3.因为无连接,所以不可靠
4.因为不需要建立连接,所以速度快
5.udp不分服务端与客户端的,只分发送端与接收端.
比如:物管的对讲机,feiq聊天,游戏.........
2.2、UDP协议下的sokect
。。。
2.3、实例
例1:(从MyEclipse向FeiQ发送信息)
package com.shore.code; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress; /**
* @author DSHORE / 2018-7-23
*
*/
/*
* 每个网络程序都有自己所处理的特定格式的数据,如果接收到的数据不符合特定的格式,那么就好被当作垃圾数据丢弃.(加密...)
*
* feiQ接收数据的格式
* Version:time:sender: ip : flag : content;
* 版本号 时间 发送人 发送的标示符 真正的内容
* 在udp协议中,有一个ip地址称为广播地址,广播地址就是主机号为255的地址
* 255.255.255.255
* 给广播Ip地址发送消息的时候,在同一网段的机器都可以接收到信息
* */
public class FeiQDemo {
public static void main(String[] args) throws IOException {
//建立udp服务
DatagramSocket datagramSocket=new DatagramSocket();
//准备数据,把数据封装到数据包中
String data=getDate("FeiQ你好"); //返回一个数组(位元组)(字节) 数组长度 获取IP地址名 端口号
DatagramPacket datagramPacket=new DatagramPacket(data.getBytes(), data.getBytes().length,InetAddress.getByName("20.15.1.255"),);
//发送数据
datagramSocket.send(datagramPacket);
//关闭资源
datagramSocket.close();
}
//把数据拼成指定格式的数据
private static String getDate(String string) {
StringBuilder sb=new StringBuilder();//建立字符串
sb.append("1.0:"); //版本号
sb.append(System.currentTimeMillis()+":"); //发送时间
sb.append("习大大:"); //发送人
sb.append("192.168.20.1:"); //IP地址(随便写的),(假地址)
sb.append("32:");//标识符
sb.append(string);//发送内容
return sb.toString();
}
}
例2:(模拟 客户端向服务端发送消息)
package com.shore.code; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket; /**
* @author DSHORE / 2018-7-23
*
*/
/*
* 接收端使用步骤:
* 1.建立udp服务,并且要监听一个端口
* 2.准备一个空的数据包来用于存储数据
* 3.调用UDP服务来接收数据
* 4.关闭资源
* */
//接收端(服务端)
public class UDPReceive {
public static void main(String[] args) throws IOException {
//1.建立udp服务,并且要监听一个端口
DatagramSocket datagramSocket=new DatagramSocket();//9090这个端口号是随便定的,但,要保证服务端和客户端的一致
//2.准备一个空的数据包来用于存储数据
byte[] buf=new byte[];
DatagramPacket datagramPacket=new DatagramPacket(buf,buf.length);
//3.调用UDP服务来接收数据
datagramSocket.receive(datagramPacket);//receive是一个阻塞型的方法,没有接收到数据之前会一直等待.数据实际上就存在到byte的字节数组中
//向控台打印数据
System.out.println("接收到的数据是:"+new String(buf, , datagramPacket.getLength()));
//4.关闭资源
datagramSocket.close();
}
}
package com.shore.code; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress; /**
* @author DSHORE / 2018-7-23
*
*/
//发送端(客户端)
public class UDPSender {
public static void main(String[] args) throws IOException {
//建立UDP服务
DatagramSocket datagramSocket=new DatagramSocket();
//准备货物,把数据封装到数据包中
String data="这是我的第一个UDP例子..";
//创建一个数据包 //返回一个数组(位元组)(字节) 数组长度 获取IP地址 端口号
DatagramPacket datagramPacket=new DatagramPacket(data.getBytes(), data.getBytes().length,InetAddress.getLocalHost(),);//9090这个端口号是随便定的,但,要保证服务端和客户端的一致
//调用UDp服务发送数据包
datagramSocket.send(datagramPacket);
datagramSocket.close();
}
}
运行结果图
例3:群聊(用线程的方式,模拟客户端向服务端发送消息)
package com.shore.code; /**
* @author DSHORE / 2018-7-23
*
*/
//主方法(主入口)
public class ChatMain {
public static void main(String[] args) {
//服务端
ChatReceive chatReceive=new ChatReceive();
chatReceive.start();
//客户端
ChatSender chatSender=new ChatSender();
chatSender.start();
}
}
package com.shore.code; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException; /**
* @author DSHORE / 2018-7-23
*
*/
//群聊接收端(服务端)
public class ChatReceive extends Thread{
@Override
public void run() {
try {
//建立一个udp服务,要监听一个端口
DatagramSocket datagramSocket=new DatagramSocket();
//准备一个空的数据包接收数据
byte[] buf=new byte[];
DatagramPacket datagramPacket=new DatagramPacket(buf,buf.length);
boolean flag=true;
while(flag){
datagramSocket.receive(datagramPacket);
System.out.println(datagramPacket.getAddress().getHostAddress()+"说:"+new String(buf,,datagramPacket.getLength()));
}
datagramSocket.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.shore.code; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException; /**
* @author DSHORE / 2018-7-23
*
*/
//群聊发送端(客户端)
public class ChatSender extends Thread{
@Override
public void run() {
try {
//建立udp服务
DatagramSocket datagramSocket=new DatagramSocket();
//准备数据,把数据封装到数据包中
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in));
String line=null;
DatagramPacket datagramPacket=null;
while((line=bufferedReader.readLine())!=null){
//把数据封装到数据包中,然后在发送
datagramPacket=new DatagramPacket(line.getBytes(),line.getBytes().length,InetAddress.getByName("192.168.191.1"),);
datagramSocket.send(datagramPacket);
}
datagramSocket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、TCP通讯协议
3.1、TCP通讯协议的特点
1.tcp基于IO流进行数据传输的,面向连接
2.TCP进行数据传输的时候是没有大小限制的.
3.TCP是面向连接,通过三次握手的机制保证数据的完整性。可靠协议
4.TCp是面向连接,所有速度慢
5.TCP分服务端与客户端
比如:打电话、QQ\飞秋的文件传输、迅雷下载....
3.2、TCP协议下的Socket
1.Socket(客户端),一旦启动马上要与服务端进行连接
2.ServerSocket(服务端)
3.3、TCP协议的三次握手
TCP是一个面向连接的协议,在正式发收数据前,必须和对方建立可靠的连接,而一个TCP连接必须经过三次握手才能建立起来。
第一次握手:建立连接时,Client发出SYN包(SYN=1,随机产生一个seq=j)到Server,并进入SYN_SEND状态,等待Server确认。
第二次握手:Server收到SYN包,确认Client的SYN,知道Client请求建立连接,将ACK置为1(ACK=1,ack=j+1),同时自己也发送一个SYN包(SYN=1,seq=k),即SYN+ACK包,此时服务端B进入SYN_RECV状态。
第三次握手:Client收到Server的SYN+ACK包,检验ACK是否为1,ack是否为j+1,正确则向Server发送确认包ACK(ACK=1,ack=k+1),Server确认ACK与ack,正确则建立连接成功,Client和Server进入ESTABLISHED状态,完成三次握手。
TCP三次握手的作用:为了防止已经失效的连接请求报文段又发送到服务端,产生错误。
3.4、实例
例1:(客户端与服务端一问一答聊天)
package com.shore.tcp; import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* @author DSHORE / 2018-7-24
*
*/
//tcp服务端
public class TCPServer {
public static void main(String[] args) throws Exception {
//建立TCP服务端,并且监听一个端口
ServerSocket serverSocket=new ServerSocket();
//接收客户端连接
Socket socket=serverSocket.accept();
//获取输入流对象,读取客户端发送过来的内容
InputStream inputStream=socket.getInputStream();
byte[] buf=new byte[];
int length=;
length=inputStream.read(buf);
System.out.println(new String(buf,,length)); //获取socket输出流对象
OutputStream outputStream=socket.getOutputStream();
outputStream.write("客户端你也好!".getBytes());
//关闭资源
serverSocket.close();
}
}
package com.shore.tcp; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket; /**
* @author DSHORE / 2018-7-24
*
*/
//需求: 客户端与服务端一问一答聊天。
//tcp客户端
public class TCPClient {
public static void main(String[] args) throws IOException, IOException {
//建立TCP的服务
Socket socket=new Socket(InetAddress.getLocalHost(),);
//取得socket输出流对象
OutputStream outputStream=socket.getOutputStream();
//利用输出流对象把数据写出
outputStream.write("服务器你好?".getBytes()); //获取到输入流,读取服务器返回的数据
InputStream inputStream=socket.getInputStream();
byte[] buf=new byte[];
int length=inputStream.read(buf);
System.out.println("客户端收到的数据是:"+new String(buf,,length));
//关闭资源
socket.close();
}
}
运行结果图
例2:(升级版:客户端与服务端一问一答聊天)
package com.shore.tcp; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket; /**
* @author DSHORE / 2018-7-24
*
*/
/*
* 需求:客户端与服务端一问一答聊天
* 1.如果使用BufferedReader的readline方法一定要加上\r\n(在outputStreamWriter.write)才把数据读出来
* 2.使用字符流一定要用flush方法
* */
//InputStreamReader:转换输入流 OutputStreamWriter:转换输出流 //一对一聊天 客户端
public class ChatClient {
public static void main(String[] args) throws IOException {
//建立TCP的客户端服务
Socket socket = new Socket(InetAddress.getLocalHost(),);
//获取socket的输出流
OutputStream outputStream = socket.getOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
//获取socket输入流对象
BufferedReader bufferedReader2 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//获取键盘的输入流对象,读取数据
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = bufferedReader.readLine()) != null){
outputStreamWriter.write(line+"\r\n");
//刷新
outputStreamWriter.flush();
//读取服务端回送的消息
line = bufferedReader2.readLine();
System.out.println("服务端会送的消息是:"+line);
}
//关闭资源
socket.close();
}
}
package com.shore.tcp; 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; /**
* @author DSHORE / 2018-7-24
*
*/
/*
* 一对一聊天 服务端
* */
public class ChatServer {
public static void main(String[] args) throws IOException {
//tcp服务端
ServerSocket serverSocket = new ServerSocket();
//接收客户端连接,产生一个socket
Socket socket=serverSocket.accept();
//获取输入流对象
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//获取socket的输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//获取键盘输入流对象
BufferedReader bufferedReader2 = new BufferedReader(new InputStreamReader(System.in));
//读取客户端信息
String line = null;
while((line = bufferedReader.readLine()) != null){
System.out.println("服务端收到的数据是:"+line);
//读取客户端发送的消息
System.out.println("请回复客户端消息:");
line = bufferedReader2.readLine();
//向客户端发送消息(写信息)
bufferedWriter.write(line+"\r\n");
//刷新
bufferedWriter.flush();
}
//关闭资源
serverSocket.close();
}
}
运行结果图
例3:
package com.shore.tcp; import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* @author DSHORE / 2018-7-24
*
*/
//TomCat
public class TomCatDemo extends Thread{
Socket socket; public TomCatDemo(Socket socket) {
super();
this.socket = socket;
} @Override
public void run() {
//获取socket输出流
try {
OutputStream outputStream=socket.getOutputStream();
//把数据写在浏览器上
outputStream.write("<html><head><title>aaa</title></head><body>你好啊浏览器</body></html>".getBytes());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
//建立tcp服务
ServerSocket serverSocket=new ServerSocket();
//
while(true){
Socket socket=serverSocket.accept();
new TomCatDemo(socket).start();
}
}
}
运行后,用IE浏览器访问的结果
原创作者:DSHORE 作者主页:http://www.cnblogs.com/dshore123/ 原文出自:https://www.cnblogs.com/dshore123/p/9355967.html 欢迎转载,转载务必说明出处。(如果本文对您有帮助,可以点击一下右下角的 推荐,或评论,谢谢!) |
检测语言 世界语 中文简体 中文繁体 丹麦语 乌克兰语 乌兹别克语 乌尔都语 亚美尼亚语 伊博语 俄语 保加利亚语 信德语 修纳语 僧伽罗语 克罗地亚语 冰岛语 加利西亚语 加泰罗尼亚语 匈牙利语 南非祖鲁语 卡纳达语 卢森堡语 印地语 印尼巽他语 印尼爪哇语 印尼语 古吉拉特语 吉尔吉斯语 哈萨克语 土耳其语 塔吉克语 塞尔维亚语 塞索托语 夏威夷语 威尔士语 孟加拉语 宿务语 尼泊尔语 巴斯克语 布尔语(南非荷兰语) 希伯来语 希腊语 库尔德语 弗里西语 德语 意大利语 意第绪语 拉丁语 拉脱维亚语 挪威语 捷克语 斯洛伐克语 斯洛文尼亚语 斯瓦希里语 旁遮普语 日语 普什图语 格鲁吉亚语 毛利语 法语 波兰语 波斯尼亚语 波斯语 泰卢固语 泰米尔语 泰语 海地克里奥尔语 爱尔兰语 爱沙尼亚语 瑞典语 白俄罗斯语 科萨 科西嘉语 立陶宛语 索马里语 约鲁巴语 缅甸语 罗马尼亚语 老挝语 芬兰语 苏格兰盖尔语 苗语 英语 荷兰语 菲律宾语 萨摩亚语 葡萄牙语 蒙古语 西班牙语 豪萨语 越南语 阿塞拜疆语 阿姆哈拉语 阿尔巴尼亚语 阿拉伯语 韩语 马其顿语 马尔加什语 马拉地语 马拉雅拉姆语 马来语 马耳他语 高棉语 齐切瓦语 |
世界语 中文简体 中文繁体 丹麦语 乌克兰语 乌兹别克语 乌尔都语 亚美尼亚语 伊博语 俄语 保加利亚语 信德语 修纳语 僧伽罗语 克罗地亚语 冰岛语 加利西亚语 加泰罗尼亚语 匈牙利语 南非祖鲁语 卡纳达语 卢森堡语 印地语 印尼巽他语 印尼爪哇语 印尼语 古吉拉特语 吉尔吉斯语 哈萨克语 土耳其语 塔吉克语 塞尔维亚语 塞索托语 夏威夷语 威尔士语 孟加拉语 宿务语 尼泊尔语 巴斯克语 布尔语(南非荷兰语) 希伯来语 希腊语 库尔德语 弗里西语 德语 意大利语 意第绪语 拉丁语 拉脱维亚语 挪威语 捷克语 斯洛伐克语 斯洛文尼亚语 斯瓦希里语 旁遮普语 日语 普什图语 格鲁吉亚语 毛利语 法语 波兰语 波斯尼亚语 波斯语 泰卢固语 泰米尔语 泰语 海地克里奥尔语 爱尔兰语 爱沙尼亚语 瑞典语 白俄罗斯语 科萨 科西嘉语 立陶宛语 索马里语 约鲁巴语 缅甸语 罗马尼亚语 老挝语 芬兰语 苏格兰盖尔语 苗语 英语 荷兰语 菲律宾语 萨摩亚语 葡萄牙语 蒙古语 西班牙语 豪萨语 越南语 阿塞拜疆语 阿姆哈拉语 阿尔巴尼亚语 阿拉伯语 韩语 马其顿语 马尔加什语 马拉地语 马拉雅拉姆语 马来语 马耳他语 高棉语 齐切瓦语 |