JAVA--基于TCP协议的Socket编程

这篇具有很好参考价值的文章主要介绍了JAVA--基于TCP协议的Socket编程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

JAVA--基于TCP协议的Socket编程

目录

        一、Socket类和ServerSocket类

1. Socket类

 2. ServerSocket类

二、 使用TCP的 Socket编程实现登录功能

1. 实现单用户登录

2. 实现多客户端用户登录

3. InetAddress类

JAVA--基于TCP协议的Socket编程

一、Socket类和ServerSocket类

        TCP具有很好的安全性能

         速度较慢

(1)java.net包的两个类Socket和ServerSocket,分别用来实现双向安全连接的客户端和服务器端,它们是基于TCP协议进行工作的,工作过程如同打电话的过程,只有双方都接通了,才能开始通话。

(2)进行网络通信时,Socket需要借助数据流来完成数据的传递工作。

(3)一个应用程序要通过网络向另一个应用程序发送数据,只要简单地创建Socket,然后将数据写入到与该Socket关联的输出流即可。对应的,接收方的应用程序创建Socket,从相关联的输入流读取数据即可。

(4)注意:2个端点在基于TCP协议的Socket编程中,经常一个作为客户端,一个作为服务器端,也就是遵循client-server模型。

1. Socket类

Socket对象在客户端和服务器之间建立连接。可用Socket类的构造方法创建套接字,并将此套接字连接至指定的主机和端口。

(1)构造方法

-->第一种构造方法以主机名和端口号作为参数来创建一个Socket对象。创建对象时可能抛出UnknownHostException或IOException异常,必须捕获它们。

Socket s = new Socket(hostName,port);

-->第二种构造方法以InetAddress对象和端口号作为参数来创建一个Socket对象。构造方法可能抛出IOException或UnknownHostException异常,必须捕获并处理它们。

Socket s = new Socket(address,port);

(2)常用方法

JAVA--基于TCP协议的Socket编程

 2. ServerSocket类

ServerSocket对象等待客户端建立连接,连接建立以后进行通信。

(1)构造方法

-->第一种构造方法接受端口号作为参数创建ServerSocket对象,创建此对象时可能抛出IOException异常,必须捕获和处理它。

ServerSocket ss = new ServerSocket(port);

-->第二种构造方法接受端口号和最大队列长度作为参数,队列长度表示系统在拒绝连接前可以拥有的最大客户端连接数。

ServerSocket ss = new ServerSocket(port,maxqu);

(2)常用方法

-->Socket类中列出的方法也适用于ServerSocket类。

-->ServerSocket类具有accept()方法,此方法用于等待客户端发起通信,这样Socket对象就可用于进一步的数据传输。

二、 使用TCP的 Socket编程实现登录功能

1. 实现单用户登录

-->Socket网络编程一般分成如下4个步骤进行:

(1)建立连接。

(2)打开Socket关联的输入/输出流。

(3)从数据流中写入信息和读取信息。

(4)关闭所有的数据流和Socket。

-->使用两个类模拟实现用户登录的功能,实现客户端向服务器端发送用户登录信息,服务器端显示这些信息。

    客户端实现步骤:

    1)建立连接,连接指向服务器及端口。

    2)打开Socket关联的输入/输出流。

    3)向输出流中写入信息。

    4)从输入流中读取响应信息。

    5)关闭所有的数据流和Socket。

    服务器端实现步骤:

    1)建立连接,监听端口。

    2)使用accept()方法等待客户端发起通信

    3)打开Socket关联的输入/输出流。

    4)从输入流中读取请求信息。

    5)向输出流中写入信息。

    6)关闭所有的数据流和Socket。

-->客户端和服务器端的交互,采用一问一答的模式,先启动服务器进入监听状态,等待客户端的连接请求,连接成功以后,客户端先“发言”,服务器给予“回应”。

1.1 客户端

package demo02;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 示例02:升级演示示例01,实现传递对象信息。
 */
public class LoginClient {

	/*
	 * 示例02:升级演示示例01,实现传递对象信息。
	 */
	
	public static void main(String[] args) {
		
		Socket socket = null;
		OutputStream os = null;
		ObjectOutputStream oos = null;
		InputStream is = null;
		BufferedReader br = null;
		
		try {
			
			// 建立客户端Socket连接,指定服务器的位置为本机以及端口为8800
			socket = new Socket("localhost", 8800);
			
			// 打开输出流
			os = socket.getOutputStream();
			
			// 对象序列化
			oos = new ObjectOutputStream(os);
			
			// 发送客户端信息,即向输出流中写入信息
			User user = new User("Tom", "123456");
			oos.writeObject(user);
			socket.shutdownOutput();

			// 接收服务器端的响应,即从输入流中读取信息
			is = socket.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			
			String reply;
			while ((reply = br.readLine()) != null) {
				System.out.println("我是客户端,服务器的响应为:" + reply);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				
				//关闭遵循 先开后关 后开先关的原则
				br.close();
				is.close();
				oos.close();
				os.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}

}

 1.2   服务器端

package demo02;

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

/**
 * 示例02:升级演示示例01,实现传递对象信息。
 * 
 */
public class LoginServer {

	public static void main(String[] args) {
		
		ServerSocket serverSocket = null;
		Socket socket = null;
		InputStream is = null;
		ObjectInputStream ois = null;
		OutputStream os = null;
		
		try {
			
			// 建立一个服务器Socket(ServerSocket),指定端口8800并开始监听
			serverSocket = new ServerSocket(8800);
			
			// 使用accept()方法等待客户端发起通信
			socket = serverSocket.accept();
			
			// 打开输入流
			is = socket.getInputStream();
			
			// 反序列化
			ois = new ObjectInputStream(is);
			
			// 获取客户端信息,即从输入流读取信息
			User user = (User) ois.readObject();
			if (user != null) {
				System.out.println("我是服务器,客户登录信息为:" + user.getLoginName() + ","
						+ user.getPwd());
			}

			// 给客户端一个响应,即向输出流中写入信息
			String reply = "欢迎你,登录成功";
			os = socket.getOutputStream();
			os.write(reply.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			// 关闭资源
			try {
				os.close();
				ois.close();
				is.close();
				socket.close();
				serverSocket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}

	}

}

1.3 定义类   实现实例化  接口

package demo02;

import java.io.Serializable;

/**
 * 示例02:升级演示示例01,实现传递对象信息
 * 
 */
public class User implements Serializable {

	private static final long serialVersionUID = 1L;
	/** 用户名 */
	private String loginName;
	/** 用户密码 */
	private String pwd;

	public User() {
		super();
	}

	public User(String loginName, String pwd) {
		super();
		this.loginName = loginName;
		this.pwd = pwd;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

}

 JAVA--基于TCP协议的Socket编程

2. 实现多客户端用户登录

-->一问一答的模式在现实中显然不是人们想要的。一个服务器不可能只针对一个客户端服务,一般是面向很多的客户端同时提供服务的,但是单线程实现必然是这样的结果。

-->解决这个问题的办法是采用多线程的方式,可以在服务器端创建一个专门负责监听的应用主服务程序、一个专门负责响应的线程程序。这样可以利用多线程处理多个请求。

->客户端实现步骤:

1)建立连接,连接指向服务器及端口。

2)打开Socket关联的输入/输出流。

3)向输出流中写入信息。

4)从输入流中读取响应信息。

5)关闭所有的数据流和Socket。

-->服务器端实现步骤:

1)创建服务器线程类,run()方法中实现对一个请求的响应处理。

2)修改服务器端代码,让服务器端Socket一直处于监听状态。

3)服务器端每监听到一个请求,创建一个线程对象并启动。

2.1 ->多个客户端*3    表示三个IP   昵称不同的三个用户   

package demo03;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 示例03:升级示例02,实现多客户端的响应处理
 * 
 
 * 
 */
public class LoginClient01 {
	/*
	 * 客户端通过输出流向服务器端发送请求信息
	 * 服务器侦听客户端的请求得到一个Socket对象,将这个Socket对象传递给线程类
	 * 线程类通过输入流获取客户端的请求并通过输出流向客户端发送响应信息
	 * 客户端通过输入流读取服务器发送的响应信息
	 * 
	 */

	/*
	 * 示例03:升级演示示例02,实现多客户端的响应处理
	 */
	public static void main(String[] args) {
		
		Socket socket = null;
		OutputStream os = null;
		ObjectOutputStream oos = null;
		InputStream is = null;
		BufferedReader br = null;
		try {
			// 建立客户端Socket连接,指定服务器的位置为本机以及端口为8800
			socket = new Socket("localhost", 8800);
			// 打开输出流
			os = socket.getOutputStream();
			// 对象序列化
			oos = new ObjectOutputStream(os);
			// 发送客户端信息,即向输出流中写入信息
			User user = new User("Tom", "123456");
			oos.writeObject(user);
			socket.shutdownOutput();

			// 接收服务器端的响应,即从输入流中读取信息
			is = socket.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			String reply;
			while ((reply = br.readLine()) != null) {
				System.out.println("我是客户端,服务器的响应为:" + reply);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				is.close();
				oos.close();
				os.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}

}

2.2 ->服务器端

package demo03;

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

/**
 * 示例03:升级示例02,实现多客户端的响应处理
 * 
 */
public class LoginServer {
	
	public static void main(String[] args) {
		
		ServerSocket serverSocket = null;
		try {
			// 建立一个服务器Socket(ServerSocket)指定端口并开始监听
			serverSocket = new ServerSocket(8800);

			// 监听一直进行中
			while (true) {
				// 使用accept()方法等待客户发起通信
				Socket socket = serverSocket.accept();
				LoginThread loginThread = new LoginThread(socket);
				loginThread.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

2.3 --->创建服务器端线程类

package demo03;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
 * 示例03:升级示例02,实现多客户端的响应处理。
 * 
 *
 */
public class LoginThread extends Thread {
	/*
	 * 示例03:升级示例02,实现多客户端的响应处理。
	 * 
	 * 分析如下:
	 * 	(1)创建服务器端线程类,run()方法中实现对一个请求的响应处理。
	 * 	(2)修改服务器端代码,让服务器端Socket一直处于监听状态。
	 * 	(3)服务器端每监听到一个请求,创建一个线程对象并启动
	 */
	
	Socket socket = null;
	//每启动一个线程,连接对应的Socket

	public LoginThread(Socket socket) {
		this.socket = socket;
	}
	
	//启动线程,即响应客户请求
	public void run() {
		InputStream is = null;
		ObjectInputStream ois = null;
		OutputStream os = null;
		try {
			//打开输入流
			is = socket.getInputStream();
			//反序列化
			ois = new ObjectInputStream(is);
			//获取客户端信息,即从输入流读取信息
			User user = (User)ois.readObject();
			if(user!=null){
				System.out.println("我是服务器,客户登录信息为:"+user.getLoginName()+","+user.getPwd());
			}
			
			//给客户端一个响应,即向输出流中写入信息
			os = socket.getOutputStream();
			String reply = "欢迎你,登录成功";
			os.write(reply.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}finally{
			try {
				os.close();
				ois.close();
				is.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
	
	}
	
}

 2.4 -->创建用户类

package demo03;

import java.io.Serializable;

/**
 * 示例03:升级示例02,实现多客户端的响应处理。

 * 
 */
public class User implements Serializable {

	private static final long serialVersionUID = 1L;
	/** 用户名 */
	private String loginName;
	/** 用户密码 */
	private String pwd;

	public User() {
		super();
	}

	public User(String loginName, String pwd) {
		super();
		this.loginName = loginName;
		this.pwd = pwd;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

}

3. InetAddress类

-->java.net包中的InetAddress类用于封装IP地址和DNS。要创建InetAddress类的实例,可以使用工厂方法,因为此类没有构造方法。

-->InetAddress类中的工厂方法

JAVA--基于TCP协议的Socket编程文章来源地址https://www.toymoban.com/news/detail-405266.html

到了这里,关于JAVA--基于TCP协议的Socket编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java】--网络编程:基于TCP协议的网络通信

    TCP协议(Transmission Control Protocol),即传输控制协议,是一种 面向连接 的, 可靠 的,基于 字节流 的传输层通信协议。数据大小无限制。 建立连接的过程需要 三次握手 。 断开连接的过程需要 四次挥手 。 使用TCP协议的通信双方分别为 客户端 和 服务器端 。 客户端负责向服务

    2024年01月23日
    浏览(61)
  • 【C语言实现windows环境下Socket编程TCP/IP协议】

    代码是别人的,问题是我的。顺便记录一下遇见的各种问题和我的解决办法。 可能的解决方案: 1、服务端和客户端不在一个局域网,可以开热点,这样就在了。然后ipconfig查看IP地址,就ok了。至于怎么查看在不在就ping一下对方就好了。 2、一个局域网下也ping不通:看看自己

    2024年02月04日
    浏览(48)
  • 基于TCP的Socket网络编程

    前言: Socket通信是基于TCP/IP协议的通信。在工作和做项目中应用非常广,下面来介绍下Socket网络编程! Socket的介绍 首先,在Socket网络编程中我们要了解两个重要的东西,ip和端口号,一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等。这些服务完全

    2024年02月11日
    浏览(45)
  • 基于TCP/UDP的Socket编程

    ---- socket概述: socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。 socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种\\\"打开—读/写—关闭\\\"模式的实现,服务器和客户端各自维护一个

    2024年02月10日
    浏览(39)
  • Java——TCP UDP Socket编程

    目录 一、网络的相关概念 (一)网络通信 (二)网络 (三)ip地址 (四)ipv4地址分类 (五)域名 (六)网络通信协议 (七)TCP和UDP 二、InetAddress类 三、Socket 四、TCP网络编程 (一)案例一——使用字节流 (二)案例二——使用字节流  (三)案例三——使用字符流 (四

    2024年02月06日
    浏览(43)
  • 「网络编程」第二讲:socket套接字(四 - 完结)_ Linux任务管理与守护进程 | TCP协议通讯流程

    「前言」文章是关于网络编程的socket套接字方面的,上一篇是网络编程socket套接字(三),这篇续上篇文章的内容,下面开始讲解!  「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 「枫叶先生有点文青病」「句子分享」 Time goes on and on, never to an 

    2024年02月10日
    浏览(66)
  • 【网络编程】网络编程概念,socket套接字,基于UDP和TCP的网络编程

    前言: 大家好,我是 良辰丫 ,今天我们一起来学习网络编程,网络编程的基本概念,认识套接字,UDP与TCP编程.💞💞💞 🧑个人主页:良辰针不戳 📖所属专栏:javaEE初阶 🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。 💦期待大家三连,关注

    2023年04月20日
    浏览(61)
  • Java网络编程基础:TCP Socket套接字编程 IntAddress UDP等...

    目录 一,网络基础 1.IP地址 2.端口 3.TCP/UDP协议 4.网络编程开发模式  二,基于套接字的Java网络编程 1.Socket  2.InetAddress 三.基于TCP的Socket网络编程 1.单服务器端与单Socket客户端一次通讯 2.单服务器端接收多次通讯  3.TCP网络通讯补充 四,基于UDP的网络编程 1. DatagramSocket:收发

    2024年04月29日
    浏览(46)
  • Java网络编程(二)Socket 套接字(TCP和UDP),以及TCP的回显

    我们软件工作者,着重编写的是应用层的代码,但是发送这个数据,我们就需要将应用层传输到传输层,也就意味着我们需要调用应用层的API,统称为 Socket API。 套接字的分类: 流套接字:使用传输层TCP协议 特点: 有连接:使用 TCP 通信的双方,需要时刻保存对方的相关消

    2024年02月09日
    浏览(54)
  • c++使用OpenSSL基于socket实现tcp双向认证ssl(使用TSL协议)代码实现

    相信各位对OpenSSL库已经不陌生了,目前笔者使用这个库实现了RSA、AES加解密和tcp的双向认证功能,下面来看tcp的双向认证。 简单说双向认证就是:客户端认证服务端是否合法,服务端认证客户端是否合法 。 可以借助于HTTPS来说明,http网络传输协议是超文本的明文协议,也就

    2024年02月06日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包