一、网络通讯要素
【1】IP地址
InetAddress ia = InetAddress.getByName("www.baidu.com");
System.out.println(ia.getHostAddress());
System.out.println(ia.getHostName());
【2】端口号
☆范围0-65535,其中0-1024为系统使用或者保留端口
【3】传输协议
①UDP(聊天,视频共享等)
☆将数据和目的地址封包,不需要建立链接
☆每个数据报的大小限制在64k内
☆不可靠协议,速度快
②TCP
☆建立数据链接通道,可进行大数据传输
☆三次握手(在吗?在!OK!),可靠
☆必须建立链接,速度低
二、Socket
【1】要点:网络服务机制,两端都有,使用IO传输
【2】UDP-Socket:DatagramSocket
发送:①建立服务->②封装数据->③发送->⑤关闭
public class L02UDPSocketServer {
public static void main(String[] args) throws Exception {
// ①创建服务
DatagramSocket ds = new DatagramSocket(8888);
// ②封装数据
byte[] buf = "hello every one!".getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName("localhost"), 10000);
// ③发送
ds.send(dp);
// ④关闭
ds.close();
}
}
接受:①建立服务->②定义数据包接受数据->③使用receive fill数据->④按需取出->⑤关闭资源
public class L02UDPSocketClient {
public static void main(String[] args) throws Exception{
//①建立服务
DatagramSocket ds = new DatagramSocket(10000);
//②定义数据包接受数据
byte[] buff = new byte[1024];
DatagramPacket dp = new DatagramPacket(buff,buff.length);
//③接受
ds.receive(dp);
String address = dp.getAddress().getHostAddress();
int port = dp.getPort();
//④取出数据
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(MessageFormat.format("{0}:{1}[{2}]", address,port,data));
//⑤关闭资源
ds.close();
}
}
☆连续发送和接受
public static void startSever() throws Exception{
DatagramSocket ds = new DatagramSocket();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String sl = null;
while((sl = br.readLine())!=null){
if("886".equals(sl)){
break;
}
byte[] buff = sl.getBytes();
DatagramPacket dp = new DatagramPacket(buff,buff.length,InetAddress.getByName("localhost"),10000);
ds.send(dp);
}
ds.close();
}
public static void startClient() throws Exception{
DatagramSocket ds = new DatagramSocket(10000);
byte[] buff = new byte[1024];
DatagramPacket dp = new DatagramPacket(buff,buff.length);
while(true){
ds.receive(dp);
String address = dp.getAddress().getHostAddress();
int port = dp.getPort();
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(MessageFormat.format("{0}:{1}[{2}]", address,port,data));
}
}
★模拟聊天程序:
public class L04UDPTalker01 {
public static void main(String[] args) throws Exception{
DatagramSocket dsender = new DatagramSocket();
DatagramSocket dsreceiver = new DatagramSocket(10001);
new Thread(new Sender(dsender,InetAddress.getByName("localhost"),10002)).start();
new Thread(new Receiver(dsreceiver)).start();
}
}
/*发送端*/
class Sender implements Runnable{
private DatagramSocket ds;
private int port;
private InetAddress ip;
public Sender(DatagramSocket ds,InetAddress ip,int port){
this.ds = ds;
this.port = port;
this.ip = ip;
}
public void run(){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String ln = null;
while((ln=br.readLine())!=null){
if("886".equals(ln)){
break;
}
byte[] buff = ln.getBytes();
DatagramPacket dp = new DatagramPacket(buff,buff.length,ip,port);
ds.send(dp);
}
br.close();
ds.close();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
/*接收端*/
class Receiver implements Runnable{
private DatagramSocket ds;
public Receiver(DatagramSocket ds){
this.ds = ds;
}
public void run(){
try{
byte[] buff = new byte[1024];
DatagramPacket dp = new DatagramPacket(buff,buff.length);
while(true){
ds.receive(dp);
String address = dp.getAddress().getHostAddress();
int port = dp.getPort();
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(MessageFormat.format("{0}:{1}[{2}]", address,port,data));
}
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
【3】TCP-socket
客户端:①创建Socket,指定目的主机和端口②获取输出流,发送数据③关闭
服务器:①建立ServiceSocket,监听端口,②获取链接过来的客户端对象③获取输入流,读取发过来的数据④关闭客户端链接(服务器一般不关)
/*服务器端*/
public class L05TCPServer {
public static void main(String[] args) throws Exception{
//① 创建ServerSocket
ServerSocket ss = new ServerSocket(7777);
//②获取客户端链接
Socket socket = ss.accept();
//②获取输入流,读取数据
InputStream is = socket.getInputStream();
byte[] bs = new byte[1024];
int len = is.read(bs);
System.out.println(socket.getInetAddress().getHostAddress()+" >> "+new String(bs,0,len));
//>>获取输出流,回复客户端消息
OutputStream os = socket.getOutputStream();
os.write("Hello every one!".getBytes());
//④关闭链接
socket.close();
ss.close();
}
}
/*客户端*/
public class L05TCPClient {
public static void main(String[] args) throws Exception{
//①创建socket,指定ip和端口
Socket socket = new Socket("localhost", 7777);
//②获取输出流,写入数据
OutputStream os = socket.getOutputStream();
os.write("Hello Server!".getBytes());
//>>获取输入流,读取服务器回复
InputStream is = socket.getInputStream();
byte[] buff = new byte[1024];
int len = is.read(buff);
System.out.println(socket.getInetAddress().getHostAddress()+" >> "+new String(buff,0,len));
//③关闭链接
socket.close();
}
☆发送文件
使用socket.shutdownOutput();设置结束标记
/*客户端*/
public class L07TCPTransFileClient {
public static void main(String[] args) throws Exception{
Socket socket = new Socket("localhost",7777);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d:/java/test.png"));
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
int data = 0;
while((data = bis.read())!=-1){
bos.write(data);
}
bos.flush();
bis.close();
//设置输出流结束标记
socket.shutdownOutput();
String back = br.readLine();
System.out.println(">>"+back);
socket.close();
}
}
/*服务器端*/
public class L07TCPTransFileServer{
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(7777);
Socket s = ss.accept();
System.out.println("...已连接");
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
BufferedOutputStream boslocal = new BufferedOutputStream(new FileOutputStream("d:/java/server.png"));
int data = 0;
while((data = bis.read())!=-1){
boslocal.write(data);
}
boslocal.flush();
boslocal.close();
System.out.println("接受完成!");
pw.println("上传完成!");
s.close();
ss.close();
}
}
☆多客户端上传
public class L08TCPContinueTransFileServer {
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(7777);
while(true){
Socket s = ss.accept();
new Thread(new FileAcceptor(s)).start();
}
}
}
class FileAcceptor implements Runnable{
private Socket socket;
public FileAcceptor(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try{
int count = 0;
String ip = socket.getInetAddress().getHostAddress();
System.out.println(ip+"...Connecting");
File file = new File("d:/java/",ip+"("+(count)+").png");
while(file.exists()){
file = new File("d:/java/",ip+"("+(count++)+").png");
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
int data = 0;
while((data = bis.read())!=-1){
bos.write(data);
}
bos.close();
pw.println(ip+":OK");
socket.close();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
☆模拟用户登录
/*客户端*/
public class L09TCPLoginClient {
public static void main(String[] args) throws Exception{
Socket socket = new Socket("localhost",7777);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
BufferedReader brBack = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String sl = null;
while((sl = br.readLine())!=null){
if("over".equals(sl)){
break;
}
pw.println(sl);
String sback = brBack.readLine();
if(sback == null){
break;
}
if(sback.contains("欢迎")){
System.out.println(sback);
break;
}else{
System.out.println(sback);
}
}
br.close();
socket.close();
}
}
/*服务器端*/
public class L09TCPLoginServer {
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(7777);
while(true){
Socket s = ss.accept();
new Thread(new Loginer(s)).start();
}
}
}
class Loginer implements Runnable{
private Socket socket;
public Loginer(Socket socket){
this.socket = socket;
}
@Override
public void run() {
String ip = socket.getInetAddress().getHostAddress();
System.out.println(ip+"...connected!");
try{
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
boolean flag = false;
for (int i = 0; i < 3; i++) {
String sl = br.readLine();
System.out.println(ip+">>"+sl);
if(sl == null){
break;
}
String suser = null;
BufferedReader brUser = new BufferedReader(new InputStreamReader(new FileInputStream("d:/java/users.txt")));
while((suser = brUser.readLine())!=null){
if(suser.equals(sl)){
flag = true;
break;
}
}
brUser.close();
if(!flag){
pw.println("登录失败!");
}else{
pw.println("欢迎 "+suser+" 访问!");
break;
}
}
if(flag == false){
pw.println("用户试图暴力登录,已经关闭连接!");
}
System.out.println(ip+">>closed");
socket.shutdownOutput();
socket.close();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
☆模拟浏览器
☆ServerSocket ss = new ServerSocket(80, 50);//端口和最大链接个数(backlog)
【4】URL-URLConnection
public class L10TcpMyIE {
public static void main(String[] args) throws Exception{
Socket socket = new Socket("www.baidu.com",80);
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
out.println("GET / HTTP/1.1");//get请求,路径,协议
out.println("Host: www.baidu.com");//域名/主机
/*浏览器*/
out.println("User-Agent: Mozilla/5.0 (Windows NT 6.3; rv:31.0) Gecko/20100101 Firefox/31.0");
/*支持的MIME类型,q权重*/
out.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
/*支持的语言*/
out.println("Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
/*支持的数据压缩格式*/
out.println("Accept-Encoding: gzip, deflate");
/*链接类型*/
out.println("Connection: closed");
out.println();
out.println();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf-8"));
String ln = null;
while((ln = br.readLine())!=null){
System.out.println(ln);
}
socket.close();
}
}
☆InetSocketaddress:new Socket().connect(new InetSocketAddress("www.baidu.com", 80));//地址和端口
☆ServerSocket ss = new ServerSocket(80, 50);//端口和最大链接个数(backlog)
【4】URL-URLConnection
/*URL对象一些功能*/
public static void testUrl() throws Exception{
URL url = new URL("http://www.baidu.com/tieba/index.html?name=zhangsan&age=20");
System.out.println("getProtocol():"+url.getProtocol());//协议
System.out.println("getHost():"+url.getHost());//主机
System.out.println("getPort():"+url.getPort());//端口(-1:80)
System.out.println("getPath():"+url.getPath());//路径
System.out.println("getFile():"+url.getFile());//路径+参数
System.out.println("getQuery():"+url.getQuery());//参数
}
/*UrlConnection的使用*/
public static void testUrlConnection() throws Exception{
URL url2 = new URL("http://www.baidu.com");
URLConnection uc = url2.openConnection();
System.out.println(uc);
HttpURLConnection huc = (HttpURLConnection)uc;
BufferedReader br = new BufferedReader(new InputStreamReader(huc.getInputStream(),"utf-8"));
String ln = null;
while((ln = br.readLine())!=null){
System.out.println(ln);
}
br.close();
}