您的位置:首页 > 理论基础 > 计算机网络

黑马程序员 Java基础 网络编程

2015-08-14 08:42 447 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一 概述

1

网络应用程序由 网络编程、io流、多线程组成。

但是很多怕我们做不好,所以很多都封装起来了,我们做的最多的是造对象,调方法,造对象,调方法。

 

2网络编程三要素:

ip地址:

是网络中每台计算机的唯一标识

通过cmd中的 ipconfig可以查看本机的ip地址

 

端口号:

用来区分电脑上的每个应用程序

有效端口:0~65535,其中0~1024系统使用或保留端口

 

协议:(重点)

按照某种规则(TCP, UDP)

UDP:    数据打包,不连接

          数据报大小限制在64k

          不可靠

          速度快

应用:QQ聊天、在线视频用的都是UDP传输协议

            

TCP:      建立连接

          可以大数据量传输

          可靠(三次握手)

          速度慢

应用:FTP,File Transfer Protocol(文件传输协议)

 

二 UDP协议

1 发送

创建UDP发送端的Socket对象

创建数据并把数据打包

发送数据

释放资源

 

代码1: (InetAddress的使用)

public static void main(String[] args) {

InetAddress address = InetAddress.getByName("asd-PC");

String name = address.getName();

String ip = address.getAddress();

System.out.println(name + "   " + ip);

}


 

代码2:

public static void main(String[] args) throws IOException{

DatagramSocket ds = new DatagramSocket();

byte[] bys = "hello, udp, 我来了".getBytes();

DatagramPacket dp = new DatagramPacket(bys, bys.length,

InetAddress.getByName("asd-PC"), 10086);

ds.send(dp);

ds.close();

}


 

2 接收

创建UDP接收端的Socket对象

创建数据包用于接收数据

接收数据

解析数据包

释放资源

 

代码3:

public static void main(String[] args) {

DatagramSocket ds = new DatagramSocket(10086);

byte[] bys = new byte[1024];

DatagramPacket dp = new DatagramPacket(bys, bys.length);

ds.receive(dp);

// 解析数据包,并显示在控制台

String ip = dp.getAddress().getHostAddress();

String data = new String(dp.getData(), 0, dp.getLength())

System.out.println(ip + " : " + data);

ds.close();

}


 
3 案例

代码1: 键盘录入数据(自己控制录入结束)        send

public static void main(String[] args) {

DatagramSocket ds = new DatagramSocket();

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String line = null;

while((line = br.readLine()) != null){

if("886".equals(line)){

break;

}

byte[] bys = line.getBytes();

DatagramPacket dp = new DatagramPacket(bys, bys.length,

InetAddress.getByName("asd-PC"), 10011);

ds.send(dp);

}

ds.close();

}


 
代码2:                                         receive

public static void main(String[] args) {

DatagramSocket ds = new DatagramSocket(10011);

while(true){

byte[] bys = new byte[1024];

DatagramPacket dp = new DatagramPacket(bys, bys.length);

ds.receive(dp);

String ip = dp.getAddress().getHostAddress();

String data = new String(dp.getData(), 0, dp.getLength());

System.out.println(ip + "  " + data);

}

// 接收端应该一直开着等待接收数据,是不需要关闭

// ds.close();

}


 
代码3:  聊天室  刘意老师的05包中的

 

三 TCP协议

1 接收

  创建TCP服务器端的Socket对象

监听客户端连接

获取输入流,读取数据

释放资源

代码1:

public static void main(String[] args) {

ServerSocket ss = new ServerSocket(12345);

Socket s = ss.accept();

InputStream is = s.getInputStream();

byte[] bys = new byte[1024];

int len = is.read(bys);

String str = new String(bys, 0, len);

System.out.println( str);

String ip = s.getInetAddress().getHostAddress();

s.close();

ss.close();

}


 
2 发送

创建TCP客户端的Socket对象

获取输出流,写数据

释放资源

代码2:

public static void main(String[] args) {

Socket s = new Socket("192.168.1.101", 12345);

OutputStream os = s.getOutputStream();

os.write("hello, tcp, 我来了".getBytes());

s.close();

}


 
四 案例

 

案例一  客户端读取文本文件服务器写到文本文件

 

代码1: Server

public static void main(String[] args) {

ServerSocket ss = new ServerSocket(11114);

Socket s = ss.accept();

BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));

BufferedWriter bw = new BufferedWriter(new FileWriter(""));

String line = null;

while((line = br.readLine()) != null){

bw.write(line);

bw.newLine();

bw.flush();

}

BufferedWriter bw2 = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

bw2.write("okay");

bw2.newLine();

bw2.flush();

bw.close();

s.close();

}


 
代码2:Client

public static void main(String[] args) {

Socket s = new Socket("192.168.1.101", 11114);

BufferedReader br = new BufferedReader(new FileReader(""));

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

String line = null;

while((line = br.readLine()) != null){

bw.write(line);

bw.newLine();

bw.flush();

}

s.shutdownOutput();

BufferedReader br2 = new BufferedReader(new InputStreamReader(s.getInputStream()));

String line2 = br2.readLine();

System.out.println(line2);

br.close();

s.close();

}


 
3 理解

1)Client端的s.shutdownOutput();可以通知Server端,传输结束了,要不然(line = br.readLine())是阻塞式语句,会一直等在那里,后面的反馈及其他语句永远没法执行。

(可以下载api看一下shutdownOutput()是怎么实现的)

2)由两端对io流的封装可以想到,客户端键盘录入服务器控制台输出、客户端键盘录入服务器写到文本文件、客户端读取文本文件服务器控制台输出等案例,仅仅是对流的封装对象变了而已

 

案例2 上传图片

按照案例1的逻辑完全可以做好(我自己就敲代码实现了。所有字符流的地方变成字节流即可)

 

案例3 多线程改进上传文件

代码1: Client 不变,和之前的一样也是可以的。

 

代码2: Server端 (感觉真漂亮! )

public static void main(String[] args) throws IOException {

ServerSocket ss = new ServerSocket(11111);

while (true) {

Socket s = ss.accept();

new Thread(new UserThread(s)).start();

}

}


 
代码3: 线程

public class UserThread implements Runnable {

private Socket s;

public UserThread(Socket s) {

this.s = s;

}

public void run() {

try {

// 封装通道内的流

BufferedReader br = new BufferedReader(new InputStreamReader(

s.getInputStream()));

String newName = System.currentTimeMillis() + ".java";

BufferedWriter bw = new BufferedWriter(new FileWriter(newName));

String line = null;

while ((line = br.readLine()) != null) { // 阻塞

bw.write(line);

bw.newLine();

bw.flush();

}

BufferedWriter bwServer = new BufferedWriter(

new OutputStreamWriter(s.getOutputStream()));

bwServer.write("文件上传成功");

bwServer.newLine();

bwServer.flush();

bw.close();

s.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: