import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.io.PrintStream
import java.net.ServerSocket
import java.net.Socket
/**
* Socket通讯服务器端
* @author 米强
*
*/
public class ServerMain {
public ServerMain() {
try {
// 构造服务器ServerSocket对象,参数为服务器端开放的端口号
ServerSocket ss = new ServerSocket(30102)
System.out.println("服务器准备就绪!")
// 死循环可以使服务器持续处于接收客户端状态
while(true){
// 该方法使程序阻塞,等待客户端的链接,当监听到客户端的链接,创建一个Socket对象与客户端单独会话
Socket s = ss.accept()
// 为了不影响服务器监听其它客户端,这里开启了一个线程,由线程处理与这个客户端的会话
new ServerThread(s).start()
}
} catch (IOException e) {
e.printStackTrace()
}
}
public static void main(String[] args) {
new ServerMain()
}
}
/**
* 服务器端与客户端会话的线程
*/
class ServerThread extends Thread {
private Socket s = null
private BufferedReader read = null
private PrintStream print = null
public ServerThread(Socket s) {
this.s = s
try {
// 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流
read = new BufferedReader(new InputStreamReader(s.getInputStream()))
print = new PrintStream(s.getOutputStream())
} catch (IOException e) {
e.printStackTrace()
}
}
/**
* 线程的运行run方法
*/
public void run() {
try {
String message = null
// 这里循环可以使服务器持续的接收客户端信息。read.readLine()通过输入流读取一段字符串,赋值给message变量,如果message字符串不为“exit”则循环,否则结束循环
while (!(message = read.readLine()).equals("exit")){
// 将字符串前面添加“返回:”,再发回客户端
print.println("返回:" + message)
}
} catch (IOException e) {
} finally {
// 在 finally 代码块中无论如何都会执行下面代码:
try {
// 如果没有关闭Socket
if(!s.isClosed()){
// 关闭Socket链接
s.close()
}
} catch (IOException e1) {
e1.printStackTrace()
}
}
}
}
客户端代码:
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.io.PrintStream
import java.net.Socket
import java.net.UnknownHostException
import java.util.Scanner
/**
* Socket通讯客户端
* @author 米强
*
*/
public class ClientMain {
public ClientMain() {
try {
// 构造与服务器通讯的Socket对象,参数为服务器IP地址(String)和端口号(int),端口号需要和服务器端开放的端口号对应
Socket s = new Socket("192.168.1.100", 30102)
// 启动一个线程与服务器通讯,并把链接服务器的Socket对象传递过去
new LinkThread(s).start()
} catch (UnknownHostException e) {
e.printStackTrace()
} catch (IOException e) {
e.printStackTrace()
}
}
public static void main(String[] args) {
new ClientMain()
}
}
/**
* 与服务器通讯的线程
*/
class LinkThread extends Thread {
private Socket s = null
// 输出流
private PrintStream out = null
// 缓冲输入流
private BufferedReader in = null
// 录入文字的Scanner对象
private Scanner scanner = null
public LinkThread(Socket s) {
// 将Socket对象实例保存在全局变量中,因为run方法中我们还要用它断开链接
this.s = s
try {
// 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流
out = new PrintStream(s.getOutputStream())
in = new BufferedReader(new InputStreamReader(s.getInputStream()))
} catch (UnknownHostException e) {
e.printStackTrace()
} catch (IOException e) {
e.printStackTrace()
}
}
/**
* 线程的运行run方法
*/
public void run() {
// 构造Scanner对象
scanner = new Scanner(System.in)
System.out.println("提示:如果要结束本次会话,请输入“exit”指令!")
try {
// 死循环可以使客户端不断的向服务器发送信息,不用担心循环无法结束,后面的return语句可以结束整个线程。
while(true){
// 提示用户输入文字
System.out.print("请输入:")
// 将用户输入的字符串保存在message变量中
String message = scanner.nextLine()
// 通过输出流发送字符串
out.println(message)
// 清空缓冲,强制输出
out.flush()
// 获取服务器返回的字符串
String str = in.readLine()
// 如果返回的字符串存在
if(str != null){
// 显示在控制台
System.out.println(str)
}else{
// 提示会话结束,并结束线程
System.out.println("本次会话结束!")
return
}
}
} catch (IOException e) {
e.printStackTrace()
} finally {
// 在 finally 代码块中无论如何都会执行下面代码:
try {
// 如果没有关闭Socket
if(!s.isClosed()){
// 关闭Socket链接
s.close()
}
} catch (IOException e1) {
e1.printStackTrace()
}
}
}
}
一般的就是在数据库中的数据集中查找,如果查找到该用户就可以让其登陆。这是最简单的情况,。有的时候还要对ip进行限制,只有规定ip范围之内的才能方位登陆。
其实也没有什么特别的安全步骤。关键看你的查询语句写得怎么样了,不要被别人sql注入就是了。
短暂端口号。设置为熟知端口号53,表明这是DNS服务器端进程所发送的UDP用户数据报。1、目的端口号的值设置为49152,这是之前用户PC中发送DNS查询请求报文的DNS客户端进程所使用的短暂端口号。
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)