1.网络参考模型:
2.计算机网络:
是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
本地回环地址:127.0.0.1 主机名:localhost
3.TCP和UDP
UDP和TCP的区别:
(1)UDP
将数据及源和目的封装成数据包中,不需要建立连接
每个数据报的大小在限制在64k内
因无连接,是不可靠协议
不需要建立连接,速度快
(2)TCP
建立连接,形成传输数据的通道。
在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低
注:三次握手:
第一次:我问你在么?
第二次:你回答在。
第三次:我反馈哦我知道你在。
4.Socket(UDP传输)
Socket就是为网络服务提供的一种机制。
通信的两端都有Socket。
网络通信其实就是Socket间的通信。
数据在两个Socket间通过IO传输。
UDP传输:DatagramSocket与DatagramPacket
发送端:
建立DatagramSocket服务;
提供数据,并将数据封装到字节数组中;
创建DatagramPacket数据包,并把数据封装到包中,同时指定IP和接收端口
通过Socket服务,利用send方法将数据包发送出去;
关闭DatagramSocket和DatagramPacket服务。
DatagramSocket ds = new DatagramSocket();
byte[] by = “hello,udp”.getBytes();
DatagramPacket dp = new DatagramPacket(by,0,by.length,
InetAddress.getByName(“127.0.0.1”),10000);
ds.send(dp);
ds.close();
接收端:建立DatagramSocket服务,并监听一个端口;
定义一个字节数组和一个数据包,同时将数组封装进数据包;
通过DatagramPacket的receive方法,将接收的数据存入定义好的数据包;
通过DatagramPacke关闭t的方法,获取发送数据包中的信息;
关闭DatagramSocket和DatagramPacket服务。
DatagramSocket ds = new DatagramSocket(10000);
byte[] by = new byte[1024];
DatagramPacket dp = new DatagramPacket(by,by.length);
ds.receive(dp);
String str = new String(dp.getData(),0,dp.getLength());
System.out.println(str+"--"+dp.getAddress());
ds.close();
DatagramSocket与DatagramPacket方法摘要:方法摘要:
void close()
关闭此数据报套接字。
InetAddress getInetAddress()
返回此套接字连接的地址。
InetAddress getLocalAddress()
获取套接字绑定的本地地址。
int getPort()
返回此套接字的端口。
void receive(DatagramPacket p)
从此套接字接收数据报包。
void send(DatagramPacket p)
从此套接字发送数据报包。
5.UDP聊天程序,需两个窗口同时开启:
import java.net.*;
import java.io.*;
class UdpSend
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds = new DatagramSocket();
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=bufr.readLine())!=null)
{
if("886".equals(line))
break;
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10001);
ds.send(dp);
}
ds.close();
}
}
class UdpReceive
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds = new DatagramSocket(10001);
while(true)
{
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(buf,0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+":"+data+":"+port);
}
}
}
6.多线程UDP传输通信:
import java.net.*;
import java.io.*;
class Send implements Runnable
{
private DatagramSocket ds;
Send(DatagramSocket ds)
{
this.ds = ds;
}
public void run()
{
try
{
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line=bufr.readLine())!=null)
{
if("886".equals(line))
break;
byte[] buf = line.getBytes();
DatagramPacket dp =
new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10002);
ds.send(dp);
}
bufr.close();
ds.close();
}
catch (Exception e)
{
throw new RuntimeException("");
}
}
}
class Receive implements Runnable
{
private DatagramSocket ds;
Receive(DatagramSocket ds)
{
this.ds = ds;
}
public void run()
{
try
{
while(true)
{
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
int port = dp.getPort();
System.out.println(ip+":"+data+":"+port);
}
}
catch (Exception e)
{
throw new RuntimeException("");
}
}
}
class UdpThreadDemo
{
public static void main(String[] args) throws Exception
{
DatagramSocket dsSend = new DatagramSocket();
DatagramSocket dsRece = new DatagramSocket(10002);
new Thread(new Send(dsSend)).start();
new Thread(new Receive(dsRece)).start();
}
}
7.TCP传输:
(1)Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭socket
同样,客户端与服务器端是两个独立的应用程序。
(2)基本思路(客户端)
客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异 常。
连接成功,说明客户端与服务端建立了通道,那么 通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,通过 getInputStream(),getOutputStream()获取即可。
与服务端通讯结束后,关闭Socket。
Socket s = new Socket(“192.168.1.1”,9999);
OutputStream out = s.getOutputStream();
out.write(“hello”.getBytes());
s.close();
(3)服务端:
服务端需要明确它要处理的数据是从哪个 端口进入的。
当有客户端访问时,要明确是哪个客户 端,可通过accept()获取已连接的客户端对象,并通过该对象与客户端通过IO流进行数据传输。
当该客户端访问结束,关闭该客户端。
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept ();
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int num = in.read(buf);
String str = new String(buf,0,num);
System.out.println(s.getInetAddress().toString()+”:”+str);
s.close();
ss.close();
(4)方法摘要:void close()
关闭此套接字。
InetAddress getInetAddress()
返回套接字连接的地址。
InputStream getInputStream()
返回此套接字的输入流。
OutputStream getOutputStream()
返回此套接字的输出流。
int getPort()
返回此套接字连接到的远程端口。
void shutdownInput()
此套接字的输入流置于“流的末尾”。
void shutdownOutput()
禁用此套接字的输出流。
String toString()
将此套接字转换为 String。
8.TCP传输通信:
/*
客户端:
1.创建Socket服务,并指定要连接的服务主机
2.获取socket流中的输出流
3.获取socket输入流,输出从服务端返回的数据
*/
import java.net.*;
import java.io.*;
class TcpClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.1.100",10003);
OutputStream out = s.getOutputStream();
out.write("tcp is coming".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf,0,len));
s.close();
}
}
/*
服务端:
1.建立服务端的socket服务。ServerSocket。并监听一个端口
2.获取连接过来的客户端对象。通过ServerSocket的accept方法。
3.客户端如果发过来数据,服务端会使用对应的客户端对象,并获取该客户端的流。
4.关闭服务端。
*/
class TcpServer
{
public static void main(String[] args)throws Exception
{
ServerSocket ss = new ServerSocket(10003);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....is connecting");
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1)
{
System.out.println(new String(buf,0,len));
OutputStream out = s.getOutputStream();
out.write("client i receive".getBytes());
}
s.close();
}
}
9.客户端并发上传图片:
import java.net.*;
import java.io.*;
class PicClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.1.100",10007);
FileInputStream fis = new FileInputStream("1.jpg");
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while((len=fis.read(buf))!=-1)
{
out.write(buf,0,len);
}
s.shutdownOutput();
InputStream in = s.getInputStream();
byte[] bufIn = new byte[1024];
int lenIn = in.read(bufIn);
System.out.println(new String(bufIn,0,lenIn));
fis.close();
s.close();
}
}
class PicThread implements Runnable//让客户端访问后的执行程序封装成对象并实现Runnable
{
private Socket s;
PicThread(Socket s)
{
this.s = s;
}
public void run()
{
int count = 1;
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"....is connecting");
try
{
InputStream in = s.getInputStream();
File file = new File(ip+".jpg");
while(file.exists())//判断服务端所属文件是否重名
file = new File(ip+"("+(count++)+")"+".jpg");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while((len=in.read(buf))!=-1)
{
fos.write(buf,0,len);
}
OutputStream out = s.getOutputStream();
out.write("上传成功".getBytes());
fos.close();
s.close();
}
catch (Exception e)
{
throw new RuntimeException(ip+"图片上传失败");
}
}
}
class PicServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10007);
while(true)//服务端不断接收不同客户端
{
Socket s = ss.accept();
new Thread(new PicThread(s)).start();
}
}
}
10.建立文本转换服务器:客户端:
源:键盘录入
目的:网络设备,网络输出流
步骤:
(1)建立服务
(2)获取键盘录入
(3)将数据发给服务端
(4)获取服务端返回数据
(5)关闭资源
import java.io.*;
import java.net.*;
class TransClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.1.100",10005);
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
BufferedWriter out =
new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
BufferedReader in =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null)
{
out.write(line);
out.newLine();//服务端有readLine方法,需要回车符标记
out.flush();//缓冲区刷新后数据才会发送出去
String str = in.readLine();
System.out.println("sever:"+str);
if("over".equals(line))
break;
}
bufr.close();
s.close();
}
}
class TransServer
{
public static void main(String[] args)throws Exception
{
ServerSocket ss = new ServerSocket(10005);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"...is connecting");
BufferedReader in =
new BufferedReader(new InputStreamReader(s.getInputStream()));
//BufferedWriter out =
//new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);//可以使用PrintWriter输出流代替
String line = null;
while((line=in.readLine())!=null)
{
System.out.println(line);
out.println(line.toUpperCase());
//out.write(line.toUpperCase());
//out.newLine();//客户端也是有readLine方法,需要回车符标记。
//out.flush();
}
s.close();
}
}
11.客户端并发登陆:客户端通过键盘录入用户名,服务端对这个用户名进行校验
如果用户存在,在服务端现实xxx已登录,并在客户端现实欢迎xxx
如果用户不存在,在服务端现实xxx正在尝试登陆,并在客户端现实xxx用户不存在
最多登陆三次。
import java.net.*;
import java.io.*;
class LoginClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.1.100",10009);
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
BufferedReader in =
new BufferedReader(new InputStreamReader(s.getInputStream()));
for(int x=0;x<3;x++)
{
String line = bufr.readLine();
if(line==null)
break;
out.println(line);
String str = in.readLine();
System.out.println(str);
if(str.contains("欢迎"))
break;
}
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+"...is connecting");
try
{
for(int x=0;x<3;x++)
{
BufferedReader bufIn =
new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedReader bufr =
new BufferedReader(new FileReader("user.txt"));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
String name = bufIn.readLine();
if(name==null)
break;
String line = null;
boolean flag = false;
while((line=bufr.readLine())!=null)
{
if(line.equals(name))
{
flag = true;
break;
}
}
if(flag)
{
System.out.println(name+",已登录");
out.println(name+",欢迎登陆");
break;
}
else
{
System.out.println(name+",尝试登录");
out.println(name+",用户名不存在 ");
}
bufr.close();
}
s.close();
}
catch (Exception e)
{
throw new RuntimeException("校验失败");
}
}
}
class LoginServer
{
public static void main(String[] args) throws Exception
{
ServerSocket ss = new ServerSocket(10009);
while(true)
{
Socket s = ss.accept();
new Thread(new LoginThread(s)).start();
}
}
}
12.自定义浏览器和服务器:
import java.net.*;
import java.io.*;
/*
GET / HTTP/1.1
Host: localhost:11000
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,
User-Agent: Mozilla/5.0 (Windows NT 5.1)
Chrome/25.0.1349.2 Safari/537.21
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
*/
class MyIE
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("192.168.1.100",8080);
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
out.println("GET /myweb/demo.html HTTP/1.1");
out.println("Accept: */*");
out.println("Accept-Language: zh-CN,zh;q=0.8");
out.println("Host: 192.168.1.100:8080");
out.println("Connection: closed");
out.println();
BufferedReader bufr =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
while((line=bufr.readLine())!=null)
{
System.out.println(line);
}
bufr.close();
s.close();
}
}
class IEServer
{
public static void main(String[] args)throws Exception
{
ServerSocket ss = new ServerSocket(11000);
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+"...is connecting");
InputStream in = s.getInputStream();
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.print(new String(buf,0,len));
out.println("<font size=5 color=red>客户端 hello</font>");
s.close();
}
}