学习笔记之socket编程

来源:互联网 发布:开淘宝网需要垫资金吗 编辑:程序博客网 时间:2024/04/30 00:30

------- android培训、java培训、期待与您交流! ----------

下面是一个关于客户端登录验证的小例子:

把注意点标成了绿色,自己在做实验的时候出错了,拿出来分享一下

package fighting;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;


/**
 * 客户端通过键盘录入用户名
 * 服务器对这个用户名进行校验
 * 
 * 如果该用户存在,在服务器端显示xxx,已登录
 * 并在客户端显示xxx,欢迎光临
 * 
 * 如果该用户名不存在,在服务端显示xxx,尝试登陆
 * 并在客户端显示xxx,该用户不存在
 * 
 * 客户端最多登录3次
 *
 */
class LoginClient{
public static void main(String[] args) throws Exception{
Socket s = new Socket("localhost",10001);
//读取键盘录入
BufferedReader bufr = 
new BufferedReader(new InputStreamReader(System.in));

//注意1,PrintWriter构造函数的第一个参数是OutputStream,

                //注意2,一定不要忘记写第二个参数,不写这个参数的话,println方法不会写到服务端,也就是服务端不会接收到客户端输入的用户名,服务端进行输出的时候会显示null

PrintWriter out = 
new PrintWriter(s.getOutputStream(),true);
//BufferedReader构造函数的参数是InputStreamReader
BufferedReader bufIn = 
new BufferedReader(new InputStreamReader(s.getInputStream()));
//由于只能登录3次,所以超过3次将关闭资源
for(int i=0;i<3;i++){
String line = bufr.readLine();,
//键盘录入可能为空(例如键盘录入CTRL+C),所以对键盘录入信息进行非空判断
if(line==null)
break;
out.println(line);
//获取服务端反馈信息
String info = bufIn.readLine();
System.out.println(info);
//如果服务端返回登录成功的信息,客户端就不用再录入了,应该break跳出循环
if(info.contains("欢迎")){
break;
}
}
//判断3次将关闭资源
bufr.close();
s.close();
}
}
//每一个客户登录创建一个线程
class LoginThread implements Runnable{
private Socket s;
LoginThread(Socket s){
this.s = s;
}
public void run(){
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"connected...");
try{
//对客户端内容进行检验3次,超过3次不再校验,结束
for(int x=0;x<3;x++){
//获取客户端发送的信息
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String name = bufIn.readLine();
//如果客户端输入ctrl+c,则不再校验
if(name==null){
break;
}
System.out.println("用户"+name+"登录中...");
//读取用户列表文件
BufferedReader bufr = new BufferedReader(new FileReader("src/info.txt"));

PrintWriter out = new PrintWriter(s.getOutputStream(),true);

String line = null;
boolean flag=false;
while((line = bufr.readLine())!=null){
System.out.println(line);
if(line.equals(name)){
flag = true;
break;
}
}
if(flag){
System.out.println(name+",已登录");
out.println(name+",欢迎光临");
break;//结束3次循环
}else{
System.out.println(name+",登录失败");
out.println(name+",用户名不存在");

//注意点:校验失败,不能break,因为break了,就会跳出3次循环,这样即使客户端只登陆了1次,也将不能再登录

                                        //本人在实验时,由于从上面copy下来的,没有删掉break,导致客户端第二次输入错误的时候,出现java.net.SocketException:Software caused connectionabort: recv failed的错误,原因是客户端第一次输入错误后,进入这个else语句,就跳出了3层循环,当客户端再次输入错误后,进入不了校验语句了

//break;
}

}
s.close();
}
catch(Exception e){
throw new RuntimeException(ip+"校验失败");
}
}

}

//服务器端

class LoginServer{
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(10001);
while(true){
Socket s = ss.accept();
new Thread(new LoginThread(s)).start();
}
}
}
原创粉丝点击