黑马程序员------java基础----网络编程
2015-03-21 16:31
447 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
网络编程=网络+IO
网络模型:
OSI七层模型:物理层 数据链路层 网络层 传输层 会话层 表示层 应用层
TCP/IP参考模型:物理层 网络层 传输层 应用层
网络通讯的要素:
1.IP地址:网络中设备的标识,不容易记忆,可以使用主机名
本地回环地址127.0.0.1
广播地址X.X.X.255
2.端口号:用于标识进程的逻辑地址,是不同进程的标识。
有效端口号:0-65535,其中0-1024是系统使用或者保留端口
3.传输协议:通讯的规则,常见协议:TCP UDP
常见网络架构:
C/S:client/server
特点:
1.程序员需要开发客户端和服务端
2.维护麻烦
3.将一部分运算移到客户端来完成,减轻服务器端的压力
B/S:browser/server
特点:
1.程序员只需要开发服务端。客户端使用系统已有的浏览器即可
2.维护简单,只需维护服务端
3.所有的运算都在服务端完成
目前流行B/S
端口:物理端口
逻辑端口--软件应用程序的数字标识
传输协议:
TCP传输控制协议
面向连接,可靠的协议
需要建立连接,所以效率低
通过三次握手建立连接
UDP数据报文包协议
无连接,不可靠的协议
不需要建立连接,所以效率高
每个数据报大小限制在64K内
UDP分为发送和接收
TCP分为客户端和服务端
Socket:为网络服务提供的一种机制通信的两端都需要由Socket,数据在两个Socket之间通过IO传输
网络通信其实就是Socket之间进行通信,网络传输只能传输字节数据
1. InetAddress表示互联网协议 (IP) 地址
示例代码:
2.UDP数据报文包协议
无连接,不可靠的协议
不需要建立连接,所以效率高
每个数据报大小限制在64K内
DatagramSocket:表示用来发送和接收数据报包的套接字
DatagramPacket:此类表示数据包
数据包分为发送数据包和接收数据包
凡是发送数据包,参数都是带着地址的
UDP是无连接不可靠的协议,所以在没有接收端的情况下,发送端可以发送数据,且不会抛错,只不过是数据发丢了
示例代码:
发送数据到接收端并显示
面向连接,可靠的协议
需要建立连接,所以效率低
通过三次握手建立连接
Socket:客户端socket
ServerSocket:服务器socket
TCP是面向连接的、可靠的传输协议,如果在没有服务端的情况下,客户端发送数据,会抛错,这种情况是不允许的
代码示例:
发送数据到服务端并显示
需求:
客户端通过键盘录入发送数据到服务端
服务端将接收到的数据显示到屏幕上的同时
将这些数据转换成大写发往客户端
当客户端输入over时,大写转换结束
注意:
数据不刷新的话,因为缓冲区,数据没有被发到服务器端
数据刷新后,数据可以被发到服务器端
但是服务器端readLine中带有缓冲区,没有读到行终止符,就一直在阻塞状态
方式1:手动加行终止符
PrintWriter pw = newPrintWriter(out);
pw.print(line+"\r\n");
pw.flush();
方式2:启用打印流的自动刷新
PrintWriter pw = newPrintWriter(out,true);
pw.println(line);
代码示例:
实现多客户端的并发上传,客户端代码不需变动,服务端必须启动多个线程来实现
代码示例
客户端通过键盘录入用户名,服务端对这个用户名进行校验。
如果该用户存在,在服务端显示xxx,已登陆;并在客户端显示xxx,欢迎光临。
如果用户不存在,在服务端显示xxx,尝试登陆;并在客户端显示xxx,该用户不存在。
最多就登录三次。
代码示例:
网络编程=网络+IO
网络模型:
OSI七层模型:物理层 数据链路层 网络层 传输层 会话层 表示层 应用层
TCP/IP参考模型:物理层 网络层 传输层 应用层
网络通讯的要素:
1.IP地址:网络中设备的标识,不容易记忆,可以使用主机名
本地回环地址127.0.0.1
广播地址X.X.X.255
2.端口号:用于标识进程的逻辑地址,是不同进程的标识。
有效端口号:0-65535,其中0-1024是系统使用或者保留端口
3.传输协议:通讯的规则,常见协议:TCP UDP
常见网络架构:
C/S:client/server
特点:
1.程序员需要开发客户端和服务端
2.维护麻烦
3.将一部分运算移到客户端来完成,减轻服务器端的压力
B/S:browser/server
特点:
1.程序员只需要开发服务端。客户端使用系统已有的浏览器即可
2.维护简单,只需维护服务端
3.所有的运算都在服务端完成
目前流行B/S
端口:物理端口
逻辑端口--软件应用程序的数字标识
传输协议:
TCP传输控制协议
面向连接,可靠的协议
需要建立连接,所以效率低
通过三次握手建立连接
UDP数据报文包协议
无连接,不可靠的协议
不需要建立连接,所以效率高
每个数据报大小限制在64K内
UDP分为发送和接收
TCP分为客户端和服务端
Socket:为网络服务提供的一种机制通信的两端都需要由Socket,数据在两个Socket之间通过IO传输
网络通信其实就是Socket之间进行通信,网络传输只能传输字节数据
1. InetAddress表示互联网协议 (IP) 地址
示例代码:
public class NetDemo { public static void main(String[] args) throws Exception { //获取本地IP实例 InetAddress address=InetAddress.getLocalHost(); //输出本地IP地址以及主机名 System.out.println(address.getHostAddress()+":"+address.getHostName()); //获取指定主机的地址对象 InetAddress address2=InetAddress.getByName("192.168.1.18"); //打印指定主机的IP地址以及主机名 System.out.println(address2.getHostAddress()+":"+address2.getHostName()); InetAddress ip=InetAddress.getByName("www.baidu.com"); System.out.println(ip.getHostAddress()+":"+ip.getHostName()); } }
2.UDP数据报文包协议
无连接,不可靠的协议
不需要建立连接,所以效率高
每个数据报大小限制在64K内
DatagramSocket:表示用来发送和接收数据报包的套接字
DatagramPacket:此类表示数据包
数据包分为发送数据包和接收数据包
凡是发送数据包,参数都是带着地址的
UDP是无连接不可靠的协议,所以在没有接收端的情况下,发送端可以发送数据,且不会抛错,只不过是数据发丢了
示例代码:
发送数据到接收端并显示
/* * 通过UDP协议发送一段文本数据 * * 接收端 * 思路: * 1.先建立UDP的Socket.它具备发送或者接收功能 * 2.将数据封装到数据包中。数据包对象:DatagramPacket * 3.使用Socket对象的send方法将数据包发送出去 * 4.关闭资源 */ public class UDPSender { public static void main(String[] args) throws IOException { System.out.println("UDP发送端运行"); // 1.建立Socket DatagramSocket ds = new DatagramSocket(); // 2.将数据封装到数据包中 String text = "UDP,你好"; // 将数据转成字节数组 byte[] buff = text.getBytes(); // 将字节数组封装到数据包中 InetAddress address = InetAddress.getByName("ZFY"); DatagramPacket dp = new DatagramPacket(buff, buff.length, address, 10086); // 3.使用Socket对象的send方法发出数据包 ds.send(dp); // 4.关闭资源 ds.close(); System.out.println("发送结束"); } } /* * UDP接收端,接收发送过来的数据,并显示在屏幕上 * 思路: * 1.先有UDP Socket服务(接收端必须明确端口,否则无法接收数据) * 2.接收数据 * 3.先定义数据包 * 4.通过数据包对象获取数据包内容:发送端IP、端口、数据 * 5.关闭资源 */ public class UDPReceive { public static void main(String[] args) throws Exception { System.out.println("UDP接收端运行"); //1 创建Socket服务 DatagramSocket ds=new DatagramSocket(10086); //2 3 接收数据,将数据存储到数据包 byte[] buff=new byte[1024]; DatagramPacket dp=new DatagramPacket(buff, buff.length); ds.receive(dp);//阻塞 //4 获取数据包内容 String ipString=dp.getAddress().getHostAddress(); int port=dp.getPort(); String text=new String(dp.getData(),0,dp.getLength()); System.out.println("接收到来自"+ipString+":"+port+"的数据:"+text); //5 关闭资源 ds.close(); System.out.println("UDP接收结束"); } }键盘录入信息发到接收端,由接收端将数据发回发送端进行显示
/* * 发送端:从键盘录入数据发送到接收端,输入bye退出 * */ public class UDPSender { public static void main(String[] args) throws Exception { System.out.println("发送端启动"); System.out.println("等待输入信息..."); //创建Socket DatagramSocket socket=new DatagramSocket(10001); DatagramPacket dp=null; //获取本机地址 InetAddress address=InetAddress.getByName("127.0.0.1"); //从键盘录入信息 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String line=null; byte[] buff=null; while((line=br.readLine())!=null){ buff=line.getBytes(); //创建数据包 dp=new DatagramPacket(buff, buff.length,address,10010); //发送数据 socket.send(dp); if(("bye".equals(line))){ break; } //接收从服务端发来的信息 socket.receive(dp); //打印来自服务端的信息 System.out.println("来自接收端的信息:"+new String(dp.getData(),0,dp.getLength())); } //关闭资源 br.close(); socket.close(); System.out.println("发送端关闭"); } } /* * 接收端:接收信息并显示到控制台,返回数据给发送端,接收到bye退出 */ public class UDPReceive { public static void main(String[] args) throws Exception { System.out.println("接收端启动"); //创建Socket DatagramSocket socket=new DatagramSocket(10010); byte[] buff=new byte[1024]; //创建接收数据包 DatagramPacket recdp=new DatagramPacket(buff, buff.length); //创建发送数据包 DatagramPacket senddp=null; //接收来自客户端的数据包 socket.receive(recdp); String line=null; while((line=new String(recdp.getData(),0,recdp.getLength())) != null&&!("bye".equals(line))){ //打印来自客户端的信息 System.out.println("来自发送端的信息:"+line); byte[] sendbuff=line.getBytes(); //发送数据包到客户端 senddp=new DatagramPacket(sendbuff, sendbuff.length,recdp.getAddress(),recdp.getPort()); socket.send(senddp); //等待接收来自客户端的数据 socket.receive(recdp); } //关闭资源 socket.close(); System.out.println("接收端关闭"); } }通过UDP实现群聊
/* * 案例:通过UDP实现群聊 * 思路: * 1.这个程序中既有收,又有发,需要同时执行,需要用到多线程技术 * 一个线程负责发送,一个线程负责接收 */ public class UDPChatTest { public static void main(String[] args) throws Exception { //定义发送端socket DatagramSocket sendDs=new DatagramSocket(); //定义接收端socket DatagramSocket recDs=new DatagramSocket(10086); //发送&接收 Send send=new Send(sendDs); Receive rec=new Receive(recDs); Thread t1=new Thread(send); Thread t2=new Thread(rec); //启动线程 t1.start(); t2.start(); } } /* * 发送端代码 */ public class Send implements Runnable { private DatagramSocket ds; private DatagramPacket dp; public Send(DatagramSocket ds) { this.ds = ds; } @Override public void run() { try{ //从键盘录入信息 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String line=null; while((line=br.readLine())!=null){ byte[] by=line.getBytes(); //实现局域网群聊,每个网段的最后一位如果写成255,没有此台主机,他会发往该网段的所有主机X.X.X.255 //dp=new DatagramPacket(by, by.length,InetAddress.getByName("192.168.1.255"),10086); //发送信息到指定接收端 dp=new DatagramPacket(by, by.length,InetAddress.getByName("127.0.0.1"),10086); ds.send(dp); //输入over,则推出聊天 if("over".equals(line)){ System.out.println("关闭发送端"); break; } } ds.close(); } catch(Exception e){ e.printStackTrace(); } } } /* * 接收端代码 */ public class Receive implements Runnable { private DatagramSocket ds; private DatagramPacket dp; public Receive(DatagramSocket ds) { this.ds = ds; } @Override public void run() { while (true) { try { //接收发送到当前端口的数据 byte[] buff = new byte[1024]; dp = new DatagramPacket(buff, buff.length); ds.receive(dp); //获取发送端Ip、端口号、内容等信息 String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String content = new String(dp.getData(), 0, dp.getLength()); //打印信息到控制台 System.out.println(ip + ":" + port + ":" + content); //如果接收到的信息是over,则关闭接收端 if("over".equals(content)){ System.out.println("关闭接收端"); break; } } catch (Exception e) { e.printStackTrace(); } } } }3、TCP传输控制协议
面向连接,可靠的协议
需要建立连接,所以效率低
通过三次握手建立连接
Socket:客户端socket
ServerSocket:服务器socket
TCP是面向连接的、可靠的传输协议,如果在没有服务端的情况下,客户端发送数据,会抛错,这种情况是不允许的
代码示例:
发送数据到服务端并显示
/* * TCP实现客户端和服务端的收发过程 * * 客户端的实现:发送信息到服务端,接收服务端返回的信息并显示 */ public class TCPClient { public static void main(String[] args) throws Exception { System.out.println("客户端启动..."); //创建客户端socket Socket client=new Socket("127.0.0.1",10086); //通过socket输出流发送数据 OutputStream out=client.getOutputStream(); out.write("服务器,你好".getBytes()); //读取服务器返回的数据,通过socket输入流 InputStream in=client.getInputStream(); byte[] buf=new byte[1024]; int len=in.read(buf); String content=new String(buf,0,len); System.out.println(content); //关闭资源 client.close(); } } /* * 服务器端:接收来自客户端的数据,并发送信息到客户端 */ public class TCPServer { public static void main(String[] args) throws Exception { System.out.println("服务端启动"); //创建服务端socket ServerSocket server=new ServerSocket(10086); //获取客户端 Socket client=server.accept(); //读取客户端数据 InputStream in=client.getInputStream(); byte[] buff=new byte[1024]; int len=in.read(buff); String content=new String(buff,0,len); String ip=client.getInetAddress().getHostAddress(); System.out.println(ip+":"+content); //给客户端发送数据 OutputStream out=client.getOutputStream(); out.write("你好,客户端".getBytes()); //关闭资源 client.close(); //如果是不断的获取客户端,则不需要关闭服务端 server.close(); } }客户端和服务器之间的频繁通信
需求:
客户端通过键盘录入发送数据到服务端
服务端将接收到的数据显示到屏幕上的同时
将这些数据转换成大写发往客户端
当客户端输入over时,大写转换结束
注意:
数据不刷新的话,因为缓冲区,数据没有被发到服务器端
数据刷新后,数据可以被发到服务器端
但是服务器端readLine中带有缓冲区,没有读到行终止符,就一直在阻塞状态
方式1:手动加行终止符
PrintWriter pw = newPrintWriter(out);
pw.print(line+"\r\n");
pw.flush();
方式2:启用打印流的自动刷新
PrintWriter pw = newPrintWriter(out,true);
pw.println(line);
代码示例:
/* * 客户端: * 思路: * 1.创建客户端socket,明确地址和端口 * 2.源:键盘录入,获取要转换的数据 * 3. 目的:网络,Socket输出流 * 4.源:socket读取流,读取服务器发回来的大写数据 * 5.目的:控制台,显示大写数据 * 6.频繁的读写操作 * 7.关闭资源 * */ public class TCPClient { public static void main(String[] args) throws Exception { System.out.println("客户端运行"); // 获取目的端ip InetAddress address = InetAddress.getByName("127.0.0.1"); // 创建客户端socket Socket s = new Socket(address, 10086); // 获取键盘录入 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 获取socket读取流 OutputStream out = s.getOutputStream(); // BufferedWriter bout=new BufferedWriter(new OutputStreamWriter(out)); PrintWriter pw = new PrintWriter(out); // 获取socket输出流 InputStream in = s.getInputStream(); BufferedReader bRead = new BufferedReader(new InputStreamReader(in)); // 频繁的读写操作 String line = null; while ((line = br.readLine()) != null) { pw.println(line); if ("over".equals(line)) { break; } String upper = bRead.readLine(); System.out.println(upper); } // 关闭资源 br.close(); s.close(); } } /* * 服务端: * 思路: * 1.创建服务端socket,监听一个端口 * 2.源:socket输入流,读取客户端发来的数据 * 3.目的:socket输出流,将转成大写的数据发送给客户端 * 4.频繁的读写资源 * 5.关闭客户端 */ public class TCPServer { public static void main(String[] args) throws Exception { System.out.println("服务端运行..."); // 创建服务器socket ServerSocket ss = new ServerSocket(10086); while (true) { // 获取客户端对象 Socket s = ss.accept(); //打印客户端IP System.out.println(s.getInetAddress().getHostAddress()+"....connected"); // socket输入流 BufferedReader bin = new BufferedReader(new InputStreamReader( s.getInputStream())); // socket输出流 PrintWriter pw = new PrintWriter(s.getOutputStream(),true); // 频繁的读写操作 String line = null; while ((line = bin.readLine()) != null) { System.out.println(line); if("over".equals(line)){ break; } // 转换大写,发送给客户端 pw.println(line.toUpperCase()); pw.flush(); } s.close(); } } }TCP实现图片上传
/* * 客户端:上传图片到服务端,获取服务端发来的上传结果并显示 */ public class Client { public static void main(String[] args) throws Exception { System.out.println("客户端启动..."); // 创建客户端socket Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 10010); // 获取socket输出流 BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream()); // 读取要上传的文件 BufferedInputStream bis = new BufferedInputStream(new FileInputStream( "D:\\1.jpg")); byte[] b = new byte[2048]; int len; // 上传文件 while ((len = bis.read(b)) != -1) { bos.write(b, 0, len); } // 向服务端发送了一个结束标记,让服务端结束读取的动作 s.shutdownOutput(); // 获取从服务器端发来的上传成功的信息 InputStream in = s.getInputStream(); byte[] b2 = new byte[1024]; int len2 = in.read(b2); System.out.println(new String(b2, 0, len2)); // 关闭资源 bis.close(); s.close(); System.out.println("客户端关闭"); } } /* * 服务端:接收客户端发送来的上传文件,存到指定目录中 * 为防止出现同名覆盖,文件名=客户端ip+编号 * 操作成功,发送“上传成功”到客户端 */ public class Server { public static void main(String[] args) throws Exception { System.out.println("服务端启动.."); // 创建服务器socket ServerSocket ss = new ServerSocket(10010); while (true) { // 获取客户端socket Socket s = ss.accept(); //打印客户端IP String ip=s.getInetAddress().getHostAddress(); System.out.println(ip+"...conneced"); // 获取socket输入流 BufferedInputStream bis = new BufferedInputStream( s.getInputStream()); //新建File对象,指向目的文件夹 File dir=new File("D:\\uploadTest"); //目的文件夹不存在,则创建 if(!dir.exists()){ dir.mkdir(); } //解决上传文件的重名覆盖问题 int count=1; File desc=new File(dir,ip+"("+count+").jpg"); while(desc.exists()){ count++; desc=new File(dir,ip+"("+count+").jpg"); } // 创建输出流,指向目的地址 BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(desc)); // 复制文件 byte[] b = new byte[2048]; int len; while ((len = bis.read(b)) != -1) { bos.write(b, 0, len); } // 向客户端发送上传成功的信息 OutputStream out = s.getOutputStream(); out.write("上传成功!".getBytes()); // 关闭资源 bos.close(); s.close(); } } }多客户端并发上传
实现多客户端的并发上传,客户端代码不需变动,服务端必须启动多个线程来实现
代码示例
/* * 客户端 */ public class Client { public static void main(String[] args) throws Exception { System.out.println("客户端启动..."); // 创建客户端socket Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 10010); // 获取socket输出流 BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream()); // 读取要上传的文件 BufferedInputStream bis = new BufferedInputStream(new FileInputStream( "D:\\1.jpg")); byte[] b = new byte[2048]; int len; // 上传文件 while ((len = bis.read(b)) != -1) { bos.write(b, 0, len); } // 向服务端发送了一个结束标记,让服务端结束读取的动作 s.shutdownOutput(); // 获取从服务器端发来的上传成功的信息 InputStream in = s.getInputStream(); byte[] b2 = new byte[1024]; int len2 = in.read(b2); System.out.println(new String(b2, 0, len2)); // 关闭资源 bis.close(); s.close(); System.out.println("客户端关闭"); } } /* * 要想实现多个客户端并发上传,服务器必须启动多个线程来完成 */ public class Server { public static void main(String[] args) throws Exception { System.out.println("服务端启动.."); // 创建服务器socket ServerSocket ss = new ServerSocket(10010); while (true) { // 获取客户端socket Socket s = ss.accept(); //将客户端socket封装进Upload,启动线程 new Thread(new Upload(s)).start(); } } } /* * 实现上传的方法 */ public class Upload implements Runnable { private Socket s; public Upload(Socket s) { this.s = s; } @Override public void run() { try { // 打印客户端IP String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + "...conneced"); // 获取socket输入流 BufferedInputStream bis = new BufferedInputStream( s.getInputStream()); // 新建File对象,指向目的文件夹 File dir = new File("D:\\uploadTest"); // 目的文件夹不存在,则创建 if (!dir.exists()) { dir.mkdir(); } // 解决上传文件的重名覆盖问题 int count = 1; File desc = new File(dir, ip + "(" + count + ").jpg"); while (desc.exists()) { count++; desc = new File(dir, ip + "(" + count + ").jpg"); } // 创建输出流,指向目的地址 BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream(desc)); // 复制文件 byte[] b = new byte[2048]; int len; while ((len = bis.read(b)) != -1) { bos.write(b, 0, len); } // 向客户端发送上传成功的信息 OutputStream out = s.getOutputStream(); out.write("上传成功!".getBytes()); // 关闭资源 bos.close(); s.close(); } catch (Exception e) { e.printStackTrace(); } } }客户端并发登录
客户端通过键盘录入用户名,服务端对这个用户名进行校验。
如果该用户存在,在服务端显示xxx,已登陆;并在客户端显示xxx,欢迎光临。
如果用户不存在,在服务端显示xxx,尝试登陆;并在客户端显示xxx,该用户不存在。
最多就登录三次。
代码示例:
import java.io.*; import java.net.*; //客户端 class LoginClient { public static void main(String[] args) throws Exception { //创建服务 Socket s=new Socket("localhost",10000); //键盘录入 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); //用Socket服务输出流写入数据 PrintWriter out =new PrintWriter(s.getOutputStream(),true ); //接收服务器返回的信息 BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); String line=null; for(int x=0;x<3;x++) { line=br.readLine();//读取键盘录入 if (line==null) { break;//如果键盘没有输入,则直接结束 } out.println(line);//将数据写入流中 String info=in.readLine();//读取返回信息 System.out.println(info); if (info.contains("欢迎"))//--------------- { break;//如果登录成功,就跳出循环 } } br.close();//关流 s.close(); } } //服务端 class LoginServer { public static void main(String [] args)throws Exception { //创建服务,监听端口 ServerSocket ss=new ServerSocket(10000); while (true) { //获取客户端对象 Socket s=ss.accept(); //客户端执行线程 new Thread(new LoginThread(s)).start(); } //ss.close(); } } //利用多线程实现并发登录 class LoginThread implements Runnable { private Socket s; LoginThread(Socket s) { this.s=s; } public void run() { //获取客户端ip String ip=s.getInetAddress().getHostAddress(); System.out.println(ip+" connected....."); try { for (int x=0;x<3 ;x++ ) { //通过客户端的读取流读取数据 BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); //读取数据库中的数据,这里用文件来表示数据库 BufferedReader br=new BufferedReader(new FileReader("users.txt")); String line=in.readLine();//读取客户端数据 if (line==null)//-------------- { break;//如果客户端没有发送数据,则跳出循环 } String data=null; boolean flag=false;//设置标记 //读取数据库中的用户数据 while ((data=br.readLine())!=null) { if (line.equals(data)) { flag=true;//如果用户存在,则将标记设为true break; } } //将数据写入到指定文件中 PrintWriter out=new PrintWriter(s.getOutputStream(),true); if (flag) { System.out.println(line+",已登陆!"); out.println(line+",欢迎光临!"); break;//----------- } else { System.out.println(line+",尝试登陆!"); out.println(line+",用户名不存在!"); } } s.close();//关流 } catch (Exception e) { throw new RuntimeException("用户登陆失败"); } } }
相关文章推荐
- 黑马程序员-Java语言基础– 网络编程 第23-24天
- 黑马程序员Java基础之网络编程(net)
- 黑马程序员_Java基础--网络编程
- 黑马程序员Java培训、Android培训_网络编程的基础知识
- 黑马程序员 java基础<七>--网络编程(1)
- 黑马程序员---Java基础--24天(网络编程之二)
- 黑马程序员-java学习基础加强之网络编程
- 黑马程序员-Java基础-网络编程
- 黑马程序员 java基础之网络编程TCP
- 黑马程序员:Java基础总结----网络编程
- 黑马程序员_java基础(12)网络编程之UDP
- 黑马程序员 java基础之网络编程UDP
- 黑马程序员----JAVA基础之GUI可视化编程与枚举&网络编程
- 黑马程序员—java基础之网络编程
- 黑马程序员---Java基础--23天(网络编程之一)
- 黑马程序员-java基础学习网络编程2
- 黑马程序员_Java基础_网络编程相关小项目
- 黑马程序员-----java基础十九(java之网络编程)
- 黑马程序员__JAVA基础__网络编程
- 黑马程序员 java基础<八>--网络编程(2)