IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 基于TCP协议的通信程序 -> 正文阅读

[网络协议]基于TCP协议的通信程序

一、什么是TCP协议?

TCP---传输控制协议[有连接的协议]
优点:保证数据安全可靠
缺点:消耗大,效率低

二、TCP协议三次握手

?TCP协议在通信的时候,要求通信的双方建立起连接(面向有连接的协议)。在建立连接的过程需要经过三次握手才能完成连接的建立。

第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确定。【Client给Server发送创建连接的请求】
第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。?? ?【Server被Client发送响应信息】
第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。【Client给Server发送确认信息】

?三、建立基于TCP的网络通讯程序需要使用的类和常用方法?

上面建立基于TCP的网络通讯程序需要两套程序。
第一套程序,是建立客户端程序
java.net.Socket【套接字】创建于TCP的通讯程序的客户端对象的java类
构造方法
Scoket(InetAddress? address,int port)创建流套接字并将其连接到指定IP地址的指定端口
Scoket(String host,int port)创建流套接字并将其连接到指定主机上的指定端口
实例方法
OutputStream? ? getOutputStream()返回客户端的输出流。【与服务器的输入流连接】
InputStream?? ?getInputStream() 返回客户端的输入流。 【与服务器的输出流连接】?
?void?? ?close() 关闭客户端。
第二套程序,是建立服务器端程序
?java.net.ServerSocket 创建基于TCP的通讯程序的服务器端对象的java类
构造方法
ServerSocket(int?port) 创建绑定到指定端口的服务器套接字。
实例方法
Socket?? ?accept() 侦听要连接到此套接字并接受它。 【阻塞主线程运行】
void?? ?close() 关闭服务器。?
客户端程序的开发步骤:
?? ?1.创建客户端对象【Socket】,连接服务器
?? ?2.通过客户端对象【Socket】的getInputStream()?? ?/ getOutputStream(),得到输入输出流
?? ?3.通过得到的输入输出流对象调用read()/write()方法完成数据收发。
?? ?4.关闭输入输出流和客户端对象【Socket】。
服务器端程序的开发步骤:
?? ?1.创建服务器端对象【ServerSocket】,开启服务器
?? ?2.通过服务器端对象【ServerSocket】的accept()方法,获得连接进入服务器的客户端对象【Socket】
?? ?3.连接进入服务器的客户端对象【Socket】的getInputStream()/getOutputStream(),得到输入输出流.
?? ?4.通过得到的输入输出流对象调用read()/write()方法完成数据收发。
?? ?5.关闭输入输出流和客户端对象【Socket】以及服务器端对象【ServerSocket】。
例如1:完成客户端向服务器送数据,服务器接收到客户端发送来的数据。
客户端:

package com.wangxing.test1;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
 * 客户端向服务器发送数据
 * @author Administrator
 *
 */
public class socketTest {
	public static void main(String[] args) throws Exception {
		//创建得到本机IP的InetAddress对象
		InetAddress socketIP=null;
		//得到本机的ip【String】
		 socketIP=socketIP.getLocalHost();
		//1.创建客户端对象,开启服务器
		Socket socket=new Socket(socketIP,3309);
		//创建输出流的变量
		OutputStream out=null;
		//创建读取从键盘得到的字符串
		String info=null;
		//将字节输入流转换成字节并从键盘中得到
		BufferedReader input= new BufferedReader (new InputStreamReader(System.in));
		System.out.print("请输入客户端要传输的信息:");
		info=input.readLine();
		//2.通过客户端对象【Socket】的getInputStream()/getOutputStream(),得到输入输出流
		out=socket.getOutputStream();
		out.write(info.getBytes());
		input.close();
		out.close();
		socket.close();
	}
}

服务器端:

package com.wangxing.test1;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * 创建服务器端接受数据
 */
public class serverTest {
	public static void main(String[] args) throws Exception{
		//创建服务器端
		ServerSocket serverscoket=new ServerSocket(3309);
		System.out.println("服务器已经启动,等待客户端连接........");
		//倾听Socket	accept() 侦听要连接到此套接字并接受它。
		Socket socket=serverscoket.accept();
		//创建保存读取数据大小的变量
		int temp;
		//创建一个保存读取数据的字节数组
		byte data[]=new byte[1024];
		String string="服务器端----";
		//创建输入流对象
		InputStream serverin=null;
		serverin=socket.getInputStream();
		//将督导数据保存到字节数组中
		int length=serverin.read(data);
		//将读取得到的字节数组转换成字符串
		String datastr=new String (data);
		System.out.println(string+datastr);
		serverin.close();
		serverscoket.close();
	}
}

例如2:完成客户端持续向服务器送数据,服务器持续接收到客户端发送来的数据。
客户端:

package com.wangxing.test2;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
 * 客户端向服务器发送数据
 * @author Administrator
 *
 */
public class socketTest {
	public static void main(String[] args) throws Exception {
		//创建得到本机IP的InetAddress对象
		InetAddress socketIP=null;
		//得到本机的ip【String】
		 socketIP=socketIP.getLocalHost();
		 //创建判断持续行为的变量
		 boolean flag=true;
		//1.创建客户端对象,开启服务器
		Socket socket=new Socket(socketIP,3309);
		//创建输出流的变量
		OutputStream out=null;
		//创建读取从键盘得到的字符串
		String info=null;
		//将字节输入流转换成字节并从键盘中得到
		BufferedReader input= new BufferedReader (new InputStreamReader(System.in));
		while(flag){
			System.out.print("请输入客户端要传输的信息:");
			info=input.readLine();
			//2.通过客户端对象【Socket】的getInputStream()/getOutputStream(),得到输入输出流
			out=socket.getOutputStream();
			out.write(info.getBytes());
			if(info.equals("exit")){
				flag=false;
			}
		}
		input.close();
		out.close();
		socket.close();
	}
}

服务端:

package com.wangxing.test2;

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * 创建服务器端接受数据
 */
public class serverTest {
	public static void main(String[] args) throws Exception{
		//创建服务器端
		ServerSocket serverscoket=new ServerSocket(3309);
		System.out.println("服务器已经启动,等待客户端连接........");
		//倾听Socket	accept() 侦听要连接到此套接字并接受它。
		Socket socket=serverscoket.accept();
		//创建保存读取数据大小的变量
		int temp;
		//创建一个判断持续的变量
		boolean flag=true; 
		//创建一个保存读取数据的字节数组
		byte data[]=new byte[1024];
		String string="服务器端----";
		//创建输入流对象
		InputStream serverin=null;
		while(flag){
			serverin=socket.getInputStream();
			//将督导数据保存到字节数组中
			int length=serverin.read(data);
			//将读取得到的字节数组转换成字符串
			String datastr=new String (data,0,length);
			System.out.println(string+datastr);
			if(datastr.equals("exit")){
				flag=false;
			}
		}
		serverin.close();
		serverscoket.close();
	}
}

例如3:完成客户端持续向服务器送数据,还能接收服务器返回的信息,服务器持续接收到客户端发送来的数据,还可以向客户端返回信息。
客户端:

package com.wangxing.test3;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
 * 客户端向服务器发送数据
 * @author Administrator
 *
 */
public class socketTest {
	public static void main(String[] args) throws Exception {
		//创建得到本机IP的InetAddress对象
		InetAddress socketIP=null;
		//得到本机的ip【String】
		 socketIP=socketIP.getLocalHost();
		 //创建判断持续行为的变量
		 boolean flag=true;
		//1.创建客户端对象,开启服务器
		Socket socket=new Socket(socketIP,3309);
		//创建输出流的变量
		OutputStream out=null;
		//创建输入流的变量
		InputStream in=null;
		//创建读取从键盘得到的字符串
		String info=null;
		//创建读取服务端的信息的字节数组
		byte data[]=new byte[1024];
		//将字节输入流转换成字节并从键盘中得到
		BufferedReader input= new BufferedReader (new InputStreamReader(System.in));
		while(flag){
			System.out.print("请输入客户端要传输的信息:");
			info=input.readLine();
			//2.通过客户端对象【Socket】的getInputStream()/getOutputStream(),得到输入输出流
			out=socket.getOutputStream();
			out.write(info.getBytes());
			if(info.equals("exit")){
				flag=false;
			}else {
				in=socket.getInputStream();
				int len=in.read(data);
				String datastr=new String(data,0,len);
				System.out.println(datastr);
			}
		}
		input.close();
		out.close();
		in.close();
		socket.close();
	}
}

服务器端:

package com.wangxing.test3;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
 * 创建服务器端接受数据
 */
public class serverTest {
	public static void main(String[] args) throws Exception{
		//创建服务器端
		ServerSocket serverscoket=new ServerSocket(3309);
		System.out.println("服务器已经启动,等待客户端连接........");
		//倾听Socket	accept() 侦听要连接到此套接字并接受它。
		Socket socket=serverscoket.accept();
		//创建保存读取数据大小的变量
		int temp;
		//创建一个判断持续的变量
		boolean flag=true; 
		//创建一个保存读取数据的字节数组
		byte data[]=new byte[1024];
		String string="server---";
		//创建输入流对象
		InputStream serverin=null;
		//创建输出流对象
		OutputStream serverout=null;
		while(flag){
			serverin=socket.getInputStream();
			//将督导数据保存到字节数组中
			int length=serverin.read(data);
			//将读取得到的字节数组转换成字符串
			String datastr=new String (data,0,length);
			System.out.println("服务器接收的数据是:"+datastr);
			if(datastr.equals("exit")){
				flag=false;
			}else{
				string=string+datastr;
				serverout=socket.getOutputStream();
				serverout.write(string.getBytes());;
			}
		}
		serverin.close();
		serverout.close();
		serverscoket.close();
	}
}

?例如4:多客户端,配置一台服务器,独立运行
客户端:

package com.wangxing.test4;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
/**
 * 客户端向服务器发送数据
 * @author Administrator
 *
 */
public class socketTest {
	public static void main(String[] args) throws Exception {
		//创建得到本机IP的InetAddress对象
		InetAddress socketIP=null;
		//得到本机的ip【String】
		 socketIP=socketIP.getLocalHost();
		 //创建判断持续行为的变量
		 boolean flag=true;
		//1.创建客户端对象,开启服务器
		Socket socket=new Socket(socketIP,3309);
		//创建输出流的变量
		OutputStream out=null;
		//创建输入流的变量
		InputStream in=null;
		//创建读取从键盘得到的字符串
		String info=null;
		//创建读取服务端的信息的字节数组
		byte data[]=new byte[1024];
		//将字节输入流转换成字节并从键盘中得到
		BufferedReader input= new BufferedReader (new InputStreamReader(System.in));
		while(flag){
			System.out.print("请输入客户端要传输的信息:");
			info=input.readLine();
			//2.通过客户端对象【Socket】的getInputStream()/getOutputStream(),得到输入输出流
			out=socket.getOutputStream();
			out.write(info.getBytes());
			if(info.equals("exit")){
				flag=false;
			}else {
				in=socket.getInputStream();
				int len=in.read(data);
				String datastr=new String(data,0,len);
				System.out.println(datastr);
			}
		}
		input.close();
		out.close();
		in.close();
		socket.close();
	}
}

服务器得到客户端对象的线程

package com.wangxing.test4;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/*
 * 创建从服务器端倾听的得到的客户端对象
 */
public class serverThread implements Runnable {
	// 创建倾听Socket accept() 侦听要连接到此套接字并接受它返回的客户端对象
	private Socket socket = null;
	// 创建输入流对象
	private InputStream serverin = null;
	// 创建一个判断持续的变量
	private boolean flag = true;
	// 创建输出流对象
	private OutputStream serverout = null;

	// 创建服务器端线程构造方法来接收TCP通讯程序的服务器端对象
	public serverThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		try{
			// 创建一个保存读取数据的字节数组
			byte data[] = new byte[1024];
			String string = "server---";
			while (flag) {
				serverin = socket.getInputStream();
				// 将督导数据保存到字节数组中
				int length = serverin.read(data);
				// 将读取得到的字节数组转换成字符串
				String datastr = new String(data, 0, length);
				System.out.println("服务器接收的数据是:" + datastr);
				if (datastr.equals("exit")) {
					flag = false;
				} else {
					string = string + datastr;
					serverout = socket.getOutputStream();
					serverout.write(string.getBytes());
				}
			}
			serverin.close();
			serverout.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

服务器端倾听得到客户端对象

package com.wangxing.test4;

import java.net.ServerSocket;
import java.net.Socket;

/*
 * 创建服务器端接受数据
 */
public class serverTest {
	public static void main(String[] args) throws Exception{
		//创建服务器端
		ServerSocket serverscoket=new ServerSocket(3309);
		System.out.println("服务器已经启动,等待客户端连接........");
		//创建一个判断是否持续执行线程的
		boolean flag=true;
		while(flag){
			//倾听Socket	accept() 侦听要连接到此套接字并接受它。
			Socket socket=serverscoket.accept();
			//创建serverThread对象
			serverThread serverThread=new serverThread(socket);
			//创建线程对象
			Thread thread=new Thread(serverThread);
			thread.start();
		}
		serverscoket.close();
	}
}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-03 13:23:39  更:2021-12-03 13:24:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:50:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码