网络编程的基础知识
1.port端口号,表示要与那一个网络应用程序进行通信
127.0.0.1是本地回路ip地址
端口号范围 0-65535之间,0-1023之间的端口数是用于一些之名网络服务和应用。
2.tcp是应用程序之间可靠无差错的传输
TCP,输出控制协议(Transmission Control Protocol),是面向连接的信息协议。会进行差错验证,接收端会在收到数据后会回复发送端,是应答模式。
UDP,用户是举报协议(User Datagram Protocol),是无连接通信协议。不保证数据的可靠传输,但可以向若干个数据源传输数据,也可以像接受若干个数据。不安全,可能造成数据的丢失,不停发送,不关心接收端是否接受到数据。
3。TCP,UDP的数据格式:
协议类型+源IP+目标IP+源端口+目标端口+帧序号+帧数据
在这个格式中协议类型来区分是UDP还是TCP。
4.Socket是网络驱动层提供给应用程序编程的接口和一种机制。Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,socket中主要是ip和prot。
5.socket数据发送过程:
a).应用程序先产生socket;
b).应用程序调用bind将socket的信息通知给驱动程序;
c).应用程序将发送的数据传输给socket。
d).驱动程序从socket取出数据并通过网卡发送出去;
socket数据接收过程:
a).应用程序先产生socket;
b).应用程序调用bind将socket的信息通知给驱动程序;
c).驱动程序根据从网卡传输 来的数据的目标端口号,将处理后的数据传送到相应的socket中;
d).应用程序从socket中取数据。
6.UDP使用的DatagramSocket对象。
ServetSocket类用于tcp通信的服务器端,Socket类用于tcp通信的服务器和客户端。
7.start可以打开一个新的黑窗口,并且会继承前一个窗口的环境。
8.先启动接受的,后启动发送的,
9.UDP网络程序
DatagramSocket类
【其构造函数有:
public DatagramSocket()、
public DatagramSocket(int port)、
public DatagramSocket(int port,InetAddress ddr)】。
DatagramPacket类
【DatagramPacket就如同码头的发送和接收数据的集装箱。
其构造函数有:
public DatagramPack(byte[] buf,int length)(用于创建接收数据的包)、
public DatagramPack(byte[] buf,int length,InetAddress address,int port)(用于发送数据的包,必须要指定对方的地址和端口号)】
InetAddress类
【InetAddress是表示ip地址的一个类,计算机地址如“192.168.0.1”、“www.itcast.cn”等
其有把字符串ip地址转换的getByName方法。
】
10.
send(DatagramPacket p)方法
close方法
11.Udp例子
发送数据
package com.hjw;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
* 用于发送数据
*
* @author Administrator
*
*/
public class UdpSend {
// 发送数据
public static void main(String[] args) {
try {
DatagramSocket ds = new DatagramSocket();
String strInfo = "hello www.it315.org";
// 对于发送中文的时候,strInfo.length()应改为strInfo.getByte().length,
// 因为strInfo.length()是字符串个数,而strInfo.getByte().length为字节个数
ds.send(new DatagramPacket(strInfo.getBytes(), strInfo.length(),
InetAddress.getByName("192.168.2.1"), 3100));
ds.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
接收数据
package com.hjw;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpReceive {
public static void main(String[] args) {
try {
DatagramSocket ds = new DatagramSocket(3100);
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
ds.receive(dp);
String str = new String(dp.getData(), 0, dp.getLength()) + "from"
+ dp.getAddress().getHostAddress() + dp.getPort();
System.out.println(str);
ds.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
12.私有ip通过网关代理上网的原理
先是私有ip把数据发送到网关上,网关上有和私有ip相匹配的ip,同事又有一个关联的ip与internet相连,比如:
192.168.0.3--->221.101.121.57
第一步:192.168.0.3--221.101.121.57--3000--3000--hello(源ip--目标ip--端口号--端口号--数据)
第二步:166.111.111.10--221.101.121.57--1027--3000--hello(166.111.111.10是网关上与私有网ip相关联的ip,通过次Ip把数据发个外网)
注:a).如果往网要给私有ip发送数据,必须网关上有与外网关联的ip,才可以发送数据。
b).网关上的ip对也有生命周期,一段时间内私有ip没给外网发送数据,外网也没有给私有ip的计算机发送数据,那么网关上的ip对就会消失,下次私有发送数据时会在建立一个新的。
13.TCP网络程序工作原理:
tcp客户端程序与服务器端程序交互过程:
(1)服务器程序创建一个ServerSocket,然后调用accept方法等待客户来连接。
(2)客户端程序创建一个Socket并请求与服务器建立连接。
(3)服务器收到客户的连接请求,并创建一个新的Socket与该客户建立专线连接。
(4)建立连接的两个Socket在一个单独的线程(由服务器程序创建)上对话。
14.例子:
package com.hjw;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 利用tcp发送接收数据
*
* @author Administrator
*
*/
public class TcpServer {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(8001);
Socket s = ss.accept();
InputStream is = s.getInputStream();
OutputStream os = s.getOutputStream();
os.write("welcome to www.itcast.cn".getBytes());
// 只读一个
// byte[] buf = new byte[1024];
// int len = is.read(buf);
// System.out.println(new String(buf, 0, len));
// 读一行
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str = br.readLine();
System.out.println(str);
br.close();
os.close();
is.close();
s.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
15.tcp服务器程序模型的编写要点:
a).tcp服务器程序要想能接受多个客户端连接,需要循环调用servSocket.accept方法;
b).服务器程序与每个客户端连接的会话过程不能相互影响,需要在独立的线程中运行;
c).一个线程服务对象与一个服务器端socket对象相关联,共同来完成于一个客户端的会话。
16.tcp端口冲突问题:
检测方法:在命令行窗口输入netstat命令查看当前正在被使用的tcp端口号:
解决方法:通过一个配置参数来指定tcp服务程序所使用的端口号:
例如:
if(args.length<1){
ss = new ServerSocket(8001);
}else{
ss = new ServerSocket(Integer.parseInt(args));
}
**将用户指定的端口号保存到一个文件中,当服务器程序下次启动运行时,直接从文件中读取那个端口号。
17.tcp客户端程序:
package com.hjw;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* tcp的client程序
*
* @author Administrator
*
*/
public class TcpClient {
public static void main(String[] args) {
try {
// 判断传入的参数的个数是否小于2
if (args.length < 2) {
System.out.println("Usage:java tcpClient Servce");
return;
}
Socket s = new Socket(args[0], Integer.parseInt(args[1]));
InputStream isr = s.getInputStream();
OutputStream ops = s.getOutputStream();
BufferedReader brNet = new BufferedReader(
new InputStreamReader(isr));
PrintWriter pw = new PrintWriter(ops, true);
BufferedReader brKeyBoard = new BufferedReader(
new InputStreamReader(System.in));
while (true) {
String strWord = brKeyBoard.readLine();
pw.println(strWord);
if (strWord.equalsIgnoreCase("quit")) {
break;
}
System.out.println(brNet.readLine());
}
pw.close();
brNet.close();
brKeyBoard.close();
s.close();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
18.在tcp网络连接上传递对象
服务器端:
package com.hjw.object;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器端写入对象
*
* @author Administrator
*
*/
public class ObjectServer {
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(8001);
Socket s = ss.accept();
// 在服务器端只需要将对象写入
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
Student stu = new Student(19, "lisi", 21, "huaxue");
oos.writeObject(stu);
oos.close();
s.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端:
package com.hjw.object;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* 客户端接收传递来的对象
*
* @author Administrator
*
*/
public class ObjectClient {
public static void main(String[] args) {
try {
Socket s = new Socket("127.0.0.1", 8001);
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
Student stu = (Student) ois.readObject();
System.out.println("id is :" + stu.id);
System.out.println("name is :" + stu.name);
System.out.println("age is :" + stu.age);
System.out.println("department is :" + stu.department);
ois.close();
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
19.应用程序协议http和网络通信协议tcp:
【ObjectInputStrea和ObjectOutputStream可以从底层输入流中读取对象类型的数据和将对象类型的数据写入高底层输出流中。
使用ObjectInputStrea和ObjectOutputStream来包装底层网络字节流,TCP服务器和TCP客户端之间就可以传递对象类型的数据。】
tcp协议可以保证计算机之间完整传递数据,但不保证接受方是否能理解发送发的意义;http协议建立在tcp网络协议之上的,是为internte上传递文件而定义的协议,tcp协议相当于电话系统,而http协议相当于电话语言
20.区分asp、jsp与网络编程的概念
,asp、jsp用于产生网站内容的。网络编程相当于制作卫星技术,asp、jsp相当于电视节目。asp、jsp又与网络编程有相互影响,asp、jsp在制作电视节目时要考虑卫星信号的强弱,而卫星在发送数据时要考了端口号等等。
21.访问Internet网络资源
1).URL(Uniform Resource Locator)统一资源定位符,用于表示intenet网络资源的地址。
url基本组成:协议、 主机名、端口号、资源名。
例如 http: // www.itcast.cn: 8080 / index.html
2).相对URL,例如"/a.html"(表示主机上某种协议的根目录),"../a.html"(表示当前资源所在目录的父目录),“./a.html”与“a.html”表示当前目录下的文件
url=基准url+相对url;
3).URL编码规则:
-将空格转化为加号。
-对0-9,a-z,A-Z之间的字符保持不变。
-对于所以其他字符则是用这个字符在内存中的十六进制表示,并在每个字节前加%,如字符“+”用%2B表示,字符“=”用%3D表示,字符“&”用%26表示,。中文字符在内存中占用两字节,字符“中”用%D6%D0,字符国用%B9%FA表示表示。
-空格用%20表示,十六进制表示。
4).java.net包中用URLEncode和URLDecode两个类实现url编码与解码
22.http协议的会话过程:
A基于http1.0协议的客户机与服务器的信息交换过程
1).客户机和服务器建立连接后;
2).客户机向服务器发送请求;
3).服务器接到请求后向客户机回送响应信息后;
4).服务器关闭连接
只能是一次请求
B基于http1.1协议的客户机与服务器的信息交换过程
1).客户机和服务器建立连接后,
2).客户机向服务器发送请求信息,服务器接到请求后向客户机回送响应信息,这个期间客户机可以发送n次请求同时服务器响应请求,
3).服务器发出关闭连接才结束会话连接。
必须包含内容的长度content-length
23.一个完整的请求消息包括:一个请求行、若干消息头(作用:客户端与服务器有条件的请求与应答)、以及实体内容(消息头与实体之间要有空行,并且两者是可选的)。
一个完整的响应消息包括:一个状态行、若干消息头、以及实体内容(消息头与实体之间要有空行)。
telnet www.google.com 80
24.http消息头
Connection:用于处理完本次请求/响应后,客户端与服务器是否保持连接,值为keep-Alive 和close
accept-Language:指定客户机期望服务器返回文档使用的国家语言
Content-Length:表示实体的长度,单位字节
Range:用于指定服务器只需返回文档中的部分呃逆荣及内容范围,格式如下:
Range:bytes=100-599两者之间的
Range:bytes=100-表示100以后的
Range:bytes=-100表示100之前的
Content-Range:用于指定服务器返回的部分实体内容的位置信息如 :Content-Range:bytes 2532-4532/7898
25.url类
openConnection方法返回URLConnection对象
url类的setURLStreamHandlerFactory(URLStreamHandlerFactory fac)静态方法
URLStreamHandlerFactory类的createURLStreamHandler(String protocol)方法
一个http连接可以被多个httpURLConnection实例对象共享,调用httpURLConnection的disconnect方法可以关闭底层共享网络。
package com.hjw;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* url的练习
*
* @author Administrator
*
*/
public class GetGoogle {
public static void main(String[] args) {
System.out.println("获取日文页面");
getContentBYLanguage("ja");
System.out.println("/n");
System.out.println("获取中文页面");
getContentBYLanguage("zh-cn");
}
public static void getContentBYLanguage(String count) {
URL urlGoogle;
try {
urlGoogle = new URL("http://www.google.com");
HttpURLConnection googleConnection = (HttpURLConnection) urlGoogle
.openConnection();
// 设置客户机响应的语言
googleConnection.setRequestProperty("Accept-Language", count);
// 得到请求的信息
Map requests = googleConnection.getRequestProperties();
Set reqFields = requests.keySet();
Iterator itrReq = reqFields.iterator();
while (itrReq.hasNext()) {
String field = (String) itrReq.next();
System.out.println(field + ":"
+ googleConnection.getRequestProperty(field));
}
googleConnection.connect();
// 获得响应的信息
Map response = googleConnection.getHeaderFields();
Set respFields = requests.keySet();
Iterator itrResp = reqFields.iterator();
while (itrResp.hasNext()) {
String field = (String) itrResp.next();
System.out.println(field + ":"
+ googleConnection.getRequestProperty(field));
}
InputStream is = googleConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String strLine = null;
while ((strLine = br.readLine()) != null) {
System.out.println(strLine);
}
br.close();
googleConnection.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}