1、网络编程概述
    1)网络编程概述
    · 计算机网络
        是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
    · 网络编程
        就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。
    2)网络模型
    · 计算机网络之间以何种规则进行通信,就是网络模型研究问题。
    · 网络模型一般是指
        · OSI(Open System Interconnection开放系统互连)参考模型
        · TCP/IP参考模型
    3)网络参考模型图
 
2、网络编程三要素
    1)IP地址:InetAddress
    网络中设备的标识,不易记忆,可用主机名
    2)端口号
    用于标识进程的逻辑地址,不同进程的标识
    3)传输协议
  通讯的规则,常见协议:TCP,UDP
    UDP:将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小在限制在64k;因无连接,是不可靠协议;不需要建立连接,速度快
    TCP:建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低
    4)InetAddress类的使用
        · 获取任意主机:public static InetAddress getByName(String host):根据主机名或者IP地址的字符串表示得到IP地址对象
    · 主机名:getHostName
    · 主机IP地址:getHostAddress    

package netcoding;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* Created by gao on 16-1-14.
*/
/*
* 如果一个类没有构造方法:
* A:成员全部是静态的(Math,Arrays,Collections)
* B:单例设计模式(Runtime)
* C:类中有静态方法返回该类的对象(InetAddress)
* class Demo {
* private Demo(){}
*
* public static Demo getXxx() {
* return new Demo();
* }
* }
*
* 看InetAddress的成员方法:
* public static InetAddress getByName(String host):根据主机名或者IP地址的字符串表示得到IP地址对象
*/
public class NetDemo01 {
public static void main(String[] args) throws UnknownHostException {
InetAddress address = InetAddress.getByName("shlgao84");
String name = address.getHostName();
String ip = address.getHostAddress();
System.out.println(name + "---" + ip);
}
}
 
5)端口号
        · 物理端口 网卡口
        · 逻辑端口 我们指的就是逻辑端口
    A:每个网络程序都会至少有一个逻辑端口
    B:用于标识进程的逻辑地址,不同进程的标识
    C:有效端口:0~65535,其中0~1024系统使用或保留端口。
 
3、Socket
    1)Socket套接字:网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。

    2)Socket原理机制:通信的两端都有Socket。网络通信其实就是Socket间的通信。数据在两个Socket间通过IO传输。
 
4、UDP传输
    · DatagramSocket与DatagramPacket
    · 建立发送端,接收端。
    · 建立数据包。
    · 调用Socket的发送接收方法。
    · 关闭Socket。
    · 发送端与接收端是两个独立的运行程序。
    1)UDP传输-发送端思路
        A:建立udp的socket服务
        B:将要发送的数据封装成数据包
        C:通过udp的socket服务,将数据包发送出
        D:关闭资源
    2)UDP传输-接收端思路
        A:建立udp的socket服务.
        B:通过receive方法接收数据
        C:将收到的数据存储到数据包对象中
        D:通过数据包对象的功能来完成对接收到数据进行解析.
        E:可以对资源进行关闭
例子1:发送端

package netcoding;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* Created by gao on 16-1-18.
*/
public class SendDemo01 {
public static void main(String[] args) throws IOException {
// 创建发送端Socket对象
// DatagramSocket()
DatagramSocket ds = new DatagramSocket();
// 创建数据,并把数据打包
// DatagramPacket(byte[] buf, int length, InetAddress address, int port)
// 创建数据
byte[] bys = "hello,udp,我来了".getBytes();
// 长度
int len = bys.length;
// IP地址对象
InetAddress address = InetAddress.getByName("10.130.26.23");
// 端口
int port = 10086;
DatagramPacket dp = new DatagramPacket(bys,len,address,port);
// 调用Socket对象的发送方法发送数据包
// public void send(DatagramPacket p)
ds.send(dp);
// 释放资源
ds.close();
}
}

接收端:

package netcoding;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* Created by gao on 16-1-18.
*/
public class ReceiveDemo01 {
public static void main(String[] args) throws IOException {
// 创建接收端Socket对象
// DatagramSocket(int port)
DatagramSocket ds = new DatagramSocket(10086);
// 创建一个数据包(接收容器)
// DatagramPacket(byte[] buf, int length)
byte[] bys = new byte[1024];
int length = bys.length;
DatagramPacket dp = new DatagramPacket(bys, length);
// 调用Socket对象的接收方法接收数据
ds.receive(dp);// 阻塞式
// 解析数据包,并显示在控制台
// 获取对方的ip
// public InetAddress getAddress()
InetAddress address = dp.getAddress();
String ip = address.getHostAddress();
// public byte[] getData():获取数据缓冲区
// public int getLength():获取数据的实际长度
byte[] bys2 = dp.getData();
int len = dp.getLength();
String s = new String(bys2, 0, len);
System.out.println(ip + "传递的数据是:" + s);
// 释放资源
ds.close();
}
}

例子2:发送端(优化代码)

package netcoding;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* Created by gao on 16-1-18.
*/
/*
* 数据来自于键盘录入
* 键盘录入数据要自己控制录入结束。
*/
public class SendDemo02 {
public static void main(String[] args) throws IOException {
// 创建发送端的Socket对象
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("10.130.26.23"), 12345);
//DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("10.130.26.255"), 10086);
// 发送数据
ds.send(dp);
}
// 释放资源
ds.close();
}
}

接收端:

package netcoding;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* Created by gao on 16-1-18.
*/
/*
* 多次启动接收端:
* java.net.BindException: Address already in use: Cannot bind
* 端口被占用。
*/
public class ReceiveDemo02 {
public static void main(String[] args) throws IOException {
// 创建接收端的Socket对象
DatagramSocket ds = new DatagramSocket(12345);
while (true) {
// 创建一个包裹
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
// 接收数据
ds.receive(dp);
// 解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println("from:" + ip + " data is:" + s);
}
// 释放资源
// 接收端应该一直开着等待接收数据,是不需要关闭
// ds.close();
}
}
例子3:(多线程实现聊天室程序)
主函数:

package netcoding;
import java.io.IOException;
import java.net.DatagramSocket;
/**
* Created by gao on 16-1-18.
*/
public class ChatRoom {
public static void main(String[] args) throws IOException {
DatagramSocket dsSend = new DatagramSocket();
DatagramSocket dsReceive = new DatagramSocket(12306);
SendThread st = new SendThread(dsSend);
ReceiveThread rt = new ReceiveThread(dsReceive);
Thread t1 = new Thread(st);
Thread t2 = new Thread(rt);
t1.start();
t2.start();
}
}

发送线程:

package netcoding;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* Created by gao on 16-1-18.
*/
public class SendThread implements Runnable {
private DatagramSocket ds;
public SendThread(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) {
if ("886".equals(line)) {
break;
}
// 创建数据并打包
byte[] bys = line.getBytes();
// DatagramPacket dp = new DatagramPacket(bys, bys.length,
// InetAddress.getByName("192.168.12.92"), 12345);
DatagramPacket dp = new DatagramPacket(bys, bys.length,
InetAddress.getByName("10.130.26.23"), 12306);
// 发送数据
ds.send(dp);
}
// 释放资源
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

接收线程:

package netcoding;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* Created by gao on 16-1-18.
*/
public class ReceiveThread implements Runnable{
private DatagramSocket ds;
public ReceiveThread(DatagramSocket ds) {
this.ds = ds;
}
@Override
public void run() {
try {
while (true) {
// 创建一个包裹
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
// 接收数据
ds.receive(dp);
// 解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println("from " + ip + " data is : " + s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
 
5、TCP传输
    · Socket和ServerSocket
    · 建立客户端和服务器端
    · 建立连接后,通过Socket中的IO流进行数据的传输
    · 关闭socket
    · 同样,客户端与服务器端是两个独立的应用程序。
    1)TCP传输-客户端思路

  A:建立客户端的Socket服务,并明确要连接的服务器。
  B:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.
  C:通过Socket对象的方法,可以获取这两个流
  D:通过流的对象可以对数据进行传输
  E:如果传输数据完毕,关闭资源

    2)TCP传输-服务器端思路
        A:建立服务器端的socket服务,需要一个端口
        B:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
        C:通过客户端的获取流对象的方法,读取数据或者写入数据
        D:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的
 
例子1:
服务器:

package netcoding;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by gao on 16-1-18.
*/
/*
* TCP协议接收数据:
* A:创建接收端的Socket对象
* B:监听客户端连接。返回一个对应的Socket对象
* C:获取输入流,读取数据显示在控制台
* D:释放资源
*/
public class ServerDemo01 {
public static void main(String[] args) throws IOException {
// 创建接收端的Socket对象
// ServerSocket(int port)
ServerSocket ss = new ServerSocket(12306);
// 监听客户端连接。返回一个对应的Socket对象
// public Socket accept()
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);
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "---" + str);
// 释放资源
s.close();
// ss.close(); //这个不应该关闭
}
}

客户端:

package netcoding;
import com.sun.org.apache.xml.internal.serializer.OutputPropertyUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
/**
* Created by gao on 16-1-18.
*/
/*
* TCP协议发送数据:
* A:创建发送端的Socket对象
* 这一步如果成功,就说明连接已经建立成功了。
* B:获取输出流,写数据
* C:释放资源
*
* 连接被拒绝。TCP协议一定要先看服务器。
* java.net.ConnectException: Connection refused: connect
*/
public class ClientDemo01 {
public static void main(String[] args) throws IOException{
// 创建发送端的Socket对象
// Socket(InetAddress address, int port)
// Socket(String host, int port)
// Socket s = new Socket(InetAddress.getByName("192.168.12.92"), 8888);
Socket s = new Socket("10.130.26.23",12306);
// 获取输出流,写数据
// public OutputStream getOutputStream()
OutputStream os = s.getOutputStream();
os.write("hello tcp.".getBytes());
// 释放资源
s.close();
}
}
例子2:服务器给客户端反馈
服务器

package netcoding;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Created by gao on 16-1-18.
*/
public class ServerDemo02 {
public static void main(String[] args) throws IOException {
// 创建服务器Socket对象
ServerSocket ss = new ServerSocket(12306);
// 监听客户端的连接
Socket s = ss.accept(); // 阻塞
// 获取输入流
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys); // 阻塞
String server = new String(bys, 0, len);
System.out.println("server:" + server);
// 获取输出流
OutputStream os = s.getOutputStream();
os.write("数据已经收到".getBytes());
// 释放资源
s.close();
// ss.close();
}
}

客户端

package netcoding;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
/**
* Created by gao on 16-1-18.
*/
public class ClientDemo02 {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("10.130.26.23", 12306);
// 获取输出流
OutputStream os = s.getOutputStream();
os.write("ClientDemo02".getBytes());
// 获取输入流
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys); // 阻塞
String client = new String(bys, 0, len);
System.out.println("client:" + client);
// 释放资源
s.close();
}
}
例子3:客户端键盘录入,服务器输出到控制台
服务器

package cn.itcast_08;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务器Socket对象
ServerSocket ss = new ServerSocket(22222);
// 监听客户端连接
Socket s = ss.accept();
// 包装通道内容的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
// br.close();
s.close();
// ss.close();
}
}

客户端

package cn.itcast_08;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/*
* 客户端键盘录入,服务器输出到控制台
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("192.168.12.92", 22222);
// 键盘录入数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 把通道内的流给包装一下
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
String line = null;
while ((line = br.readLine()) != null) {
// 键盘录入数据要自定义结束标记
if ("886".equals(line)) {
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
// 释放资源
// bw.close();
// br.close();
s.close();
}
}
例子4:客户端键盘录入,服务器输出文本文件
服务器端:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务器Socket对象
ServerSocket ss = new ServerSocket(23456);
// 监听客户端连接
Socket s = ss.accept();
// 封装通道内的数据
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 封装文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
// br.close();
s.close();
// ss.close();
}
}

客户端:

package cn.itcast_09;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/*
* 客户端键盘录入,服务器输出文本文件
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("192.168.12.92", 23456);
// 封装键盘录入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 封装通道内的数据
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
String line = null;
while ((line = br.readLine()) != null) {
if ("over".equals(line)) {
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
// bw.close();
// br.close();
s.close();
}
}

例子5:客户端文本文件,服务器输出到控制台

服务器端:

package cn.itcast_10;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务器Socket对象
ServerSocket ss = new ServerSocket(34567);
// 监听客户端连接
Socket s = ss.accept();
// 封装通道内的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
s.close();
}
}

客户端:

package cn.itcast_10;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
/*
* 客户端文本文件,服务器输出到控制台
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建Socket对象
Socket s = new Socket("192.168.12.92", 34567);
// 封装文本文件
BufferedReader br = new BufferedReader(new FileReader(
"InetAddressDemo.java"));
// 封装通道内的流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
s.close();
}
}
例子6:客户端文本文件,服务器输出文本文件
服务器端:

package cn.itcast_12;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class UploadServer {
public static void main(String[] args) throws IOException {
// 创建服务器端的Socket对象
ServerSocket ss = new ServerSocket(11111);
// 监听客户端连接
Socket s = ss.accept();// 阻塞
// 封装通道内的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 封装文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
String line = null;
while ((line = br.readLine()) != null) { // 阻塞
// if("over".equals(line)){
// break;
// }
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();
}
}

客户端:

package cn.itcast_12;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/*
* 按照我们正常的思路加入反馈信息,结果却没反应。为什么呢?
* 读取文本文件是可以以null作为结束信息的,但是呢,通道内是不能这样结束信息的。
* 所以,服务器根本就不知道你结束了。而你还想服务器给你反馈。所以,就相互等待了。
*
* 如何解决呢?
* A:在多写一条数据,告诉服务器,读取到这条数据说明我就结束,你也结束吧。
* 这样做可以解决问题,但是不好。
* B:Socket对象提供了一种解决方案
* public void shutdownOutput()
*/
public class UploadClient {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("192.168.12.92", 11111);
// 封装文本文件
BufferedReader br = new BufferedReader(new FileReader(
"InetAddressDemo.java"));
// 封装通道内流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
String line = null;
while ((line = br.readLine()) != null) { // 阻塞
bw.write(line);
bw.newLine();
bw.flush();
} //自定义一个结束标记
// bw.write("over");
// bw.newLine();
// bw.flush(); //Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了
s.shutdownOutput();
// 接收反馈
BufferedReader brClient = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String client = brClient.readLine(); // 阻塞
System.out.println(client);
// 释放资源
br.close();
s.close();
}
}
例子7:上传图片案例
服务器端:

package cn.itcast_13;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class UploadServer {
public static void main(String[] args) throws IOException {
// 创建服务器Socket对象
ServerSocket ss = new ServerSocket(19191);
// 监听客户端连接
Socket s = ss.accept();
// 封装通道内流
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
// 封装图片文件
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("mn.jpg"));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush();
}
// 给一个反馈
OutputStream os = s.getOutputStream();
os.write("图片上传成功".getBytes());
bos.close();
s.close();
}
}

客户端:

package cn.itcast_13;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public class UploadClient {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("192.168.12.92", 19191);
// 封装图片文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
"林青霞.jpg"));
// 封装通道内的流
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush();
} s.shutdownOutput();
// 读取反馈
InputStream is = s.getInputStream();
byte[] bys2 = new byte[1024];
int len2 = is.read(bys2);
String client = new String(bys2, 0, len2);
System.out.println(client);
// 释放资源
bis.close();
s.close();
}
}
例子8:服务器的代码用线程进行封装,这样可以模拟一个同时接收多人上传文件的服务器。(用循环也可以但是效率低,是单线程的程序)
服务器线程:

package cn.itcast_15;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class UserThread implements Runnable {
private Socket s;
public UserThread(Socket s) {
this.s = s;
}
@Override
public void run() {
try {
// 封装通道内的流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream()));
// 封装文本文件
// BufferedWriter bw = new BufferedWriter(new
// FileWriter("Copy.java"));
// 为了防止名称冲突
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();
}
}
}

服务器端:

package cn.itcast_15;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class UploadServer {
public static void main(String[] args) throws IOException {
// 创建服务器Socket对象
ServerSocket ss = new ServerSocket(11111);
while (true) {
Socket s = ss.accept();
new Thread(new UserThread(s)).start();
}
}
}

客户端:

package cn.itcast_15;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class UploadClient {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("192.168.12.92", 11111);
// 封装文本文件
// BufferedReader br = new BufferedReader(new FileReader(
// "InetAddressDemo.java"));
BufferedReader br = new BufferedReader(new FileReader(
"ReceiveDemo.java"));
// 封装通道内流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
String line = null;
while ((line = br.readLine()) != null) { // 阻塞
bw.write(line);
bw.newLine();
bw.flush();
}
// Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了
s.shutdownOutput();
// 接收反馈
BufferedReader brClient = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String client = brClient.readLine(); // 阻塞
System.out.println(client);
// 释放资源
br.close();
s.close();
}
}
 
 
 
 
 
 

Java API —— 网络编程的更多相关文章

  1. JAVA的网络编程

    网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者可能觉得网络编 ...

  2. 【转】JAVA之网络编程

    转自:火之光 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能,但是很多的初学者却因为很长一段时间无法进入网络编程的大门而放弃了对于该部分技术的学习. 在 学习网络编程以前,很多初学者 ...

  3. JAVA的网络编程【转】

    JAVA的网络编程[转] Posted on 2009-12-03 18:04 火之光 阅读(93441) 评论(20) 编辑 收藏 网络编程 网络编程对于很多的初学者来说,都是很向往的一种编程技能, ...

  4. java基础-网络编程(Socket)技术选型入门之NIO技术

    java基础-网络编程(Socket)技术选型入门之NIO技术 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传统的网络编程 1>.编写socket通信的MyServer ...

  5. Java复习——网络编程

    Java从最开始就是支持网络编程的,也正是网络使Java得到发展繁荣.在这里我记录一下如何使用Java进行网络编程,什么是Socket以及Java实现TCP,UDP的编程模型. InetAddress ...

  6. Java 学习(18):Java 序列化& 网络编程& 发送邮件

    --Java 序列化 -- 网络编程 -- 发送邮件 Java 序列化 Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据.有关对象的类型的信 ...

  7. Java学习——网络编程

    Java学习——网络编程 摘要:本文主要介绍了什么是网络编程,以及如何使用Java语言进行网络编程. 部分内容来自以下博客: https://www.cnblogs.com/renyuan/p/269 ...

  8. Netty | 第1章 Java NIO 网络编程《Netty In Action》

    目录 前言 1. Java 网络编程 1.1 Javs NIO 基本介绍 1.2 缓冲区 Buffer 1.2 通道 Channel 1.3 选择器 Selector 1.4 NIO 非阻塞网络编程原 ...

  9. 二十三、Java基础--------网络编程

    Java中另一个重要技术就是网络编程了,为了更好的学习web方向的知识,有必要对java之网络编程好好学习,本文将围绕网络编程技术进行分析. 常见的网络协议:UDP.TCP UDP 1. 将数据源和目 ...

随机推荐

  1. Allegro中板子边框不封闭导致的z-copy无法用的问题

    画一个不规则的边框,有半圆形状,导致边框不封闭,无法使用Z-COPY命令,下边是解决办法: 1 画好Outline后,选择 shape -> Compose Shape , options选项卡 ...

  2. matlab实现高斯牛顿法、Levenberg–Marquardt方法

    高斯牛顿法: function [ x_ans ] = GaussNewton( xi, yi, ri) % input : x = the x vector of 3 points % y = th ...

  3. 什么是Hadoop,怎样学习Hadoop

    Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS.HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上:而且它 ...

  4. .net 自然排序方式

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Cons ...

  5. html5游戏引擎-Pharse.js学习笔记(一)

    1.前言 前几天随着flappy bird这样的小游戏的火爆,使我这种也曾了解过html5技术的js业余爱好者也开始关注游戏开发.研究过两个个比较成熟的html5游戏引擎,感觉用引擎还是要方便一些.所 ...

  6. eclipse 配置git ssh登录

    实现需要安装git的插件,由于我使用的adt和eclipse for javaee版本两个,都已经安装了git插件,就不再演示了,网上都有. 这篇文章主要是介绍使用ssh进行认证的方式. 1.首先,配 ...

  7. 1069: [SCOI2007]最大土地面积 - BZOJ

    Description 在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大.Input 第1行一个正整数N,接下来N行,每行2个数x,y, ...

  8. shell script 的追踪与 debug

    shell script 的追踪与 debug scripts 在运行之前,最怕的就是出现语法错误的问题了!那么我们如何 debug 呢?有没有办法不需要透过直接运行该 scripts 就可以来判断是 ...

  9. 时隔8年HTML 5终于定稿!

    我们第一次谈论 HTML5 要改变世界大概是因为乔布斯,他坚持在 iOS 上不兼容 Flash,在 Adobe 统治多媒体开发的那个年代,这需要付出极大的勇气.这么多年过去了,虽然所有人都在谈论 HT ...

  10. hlsl 的tex函数

    texCUBE http://msdn.microsoft.com/en-us/library/windows/desktop/bb509687(v=vs.85).aspx