---------------------- <a href="http://edu.csdn.net/heima" target="blank">android培训</a>、<a href="http://edu.csdn.net/heima" target="blank">java培训</a>、期待与您交流! ----------------------
网络协议的定义:为计算机网络中进行数据交换而建立的规则、标准或约定的集合。例如,网络中一个微机用户和一个大型主机的操作员进行通信,由于这两个数据终端所用字符集不同,因此操作员所输入的命令彼此不认识。为了能进行通信,规定每个终端都要将各自字符集中的字符先变换为标准字符集的字符后,才进入网络传送,到达目的终端之后,再变换为该终端字符集的字符。
TCP/IP协议组之所以流行,部分原因是因为它可以用在各种各样的信道和底层协议之上。确切地说,TCP/IP协议是一组包括TCP协议和IP协议,UDP(User Datagram Protocol)协议、ICMP(Internet Control Message Protocol)协议和其他一些协议的协议组。
IP地址:IP地址用来标识计算机等网络设备的网络地址,由四个8位的二进制数组组成,中间一小数点分隔。如:192.168.3.188,192.168.0.3等
端口号:网络通信时同意机器上的不同进程的标识。其中0~1023是公认端口号,机已经公认定义或为将要公认定义的软件保留的;1024~65535是并没有公共定义的端口号,用户可以自己定义这些端口的作用。
Java中的网络编程类包括:
DatagramSocket 类、DatagramPacket 类、InetAddress 类
UDP使用UdpSend程序发送数据后,不可以在同一个控制台窗口中启动UdpRecv程序接收数据,因为接收程序运行时会一直阻塞,窗口被接收程序占用了,造成收不到数据,因此需要另外启动一个控制台窗口接收数据。可以用start命令在原控制台窗口中打开一个新的控制台窗口,这样做的好处是,新启动的窗口会完全继承打开它的那个窗口的环境特性,不必再手工用cd命令进入指定目录,这样就不用再配置classpath环境变量了。
在张老师的视频中,关于网络编程这一节编写一个最简单的UDP程序中。
在UdpSend发送数据程序中有一段这样的代码:
ds.send(new DatagramPacket("hello www.it315.org".getBytes(),"hello (),
InetAddress.getByName("192.168.0.3"),3000));
在接收端收到的数据为:hello www.it315.org from 192.168.0.3:1095
如果将这段代码改为:
ds.send(new DatagramPacket("hello IT资讯交流网".getBytes(),"hello IT资讯交流网".length(),
InetAddress.getByName("192.168.0.3"),3000));
则在接收端收到的数据为:from 192.168.0.3:1095
原因在于在发送的字符串中出现了中文字符时,中文字符转换为字节时是两个字节,因此"hello IT资讯交流网".length()的字符串长度小于实际得到的字节数组的字节长度,而我们在这里要发送的是字节个数不是字符个数。因此会出现接收到的数据丢失的问题。
如果将这段代码改为这样,
ds.send(new DatagramPacket("hello IT资讯交流网".getBytes(),"hello IT资讯交流网".getBytes().length(),
InetAddress.getByName("192.168.0.3"),3000));
以上问题就可以解决了。
UDP协议与TCP协议的区别:
1、TCP是面向连接的协议,而UDP是面向非连接的协议。
2、TCP的传输可靠,而UDP适用于对可靠性要求不高的应用环境。
3、TCP一次可以传输大量数据,而UDP适用于一次只传输少量数据
4、TCP的传输速度慢,而UDP的传输速度快
怎样理解应用程序协议和网络通信协议的关系?
TCP协议可以保证计算机之间正确的传送数据,但是不保证接收方是否能理解发送方数据的意义,而FTP协议是建立在TCP协议之上的,为在Internet网络上传送文件而定义的一种协议。所以TCP协议相当于电话系统,而FTP协议相当于打电话的人所约定的语言规则。
怎么区分ASP,JSP与网络编程的概念:
有很多书籍名叫什么网络编程高级技术和网络编程大全等待,打开一看,原来所谓的网络编程就是指ASP,JSP,PHP等网站相关的脚本语言的讲解,以至于很多初学者认为ASP,JSP等就是网络编程。
我要告诉大家一个事实,这是错的,我们把网络编程想成一个卫星系统的制造,在卫星系统上可以传送电视节目用的视频编辑系统。ASP,JSP产生的网页内容通过网络程序传送,就好比视频编辑系统的电视节目在卫星系统上传送一样的道理,做电视节目的人绝对不能说自己是搞卫星的制造的,ASP,JSP是用于产生网站内容,而不是用于编写网络程序的。
类 URL(Uniform Resource Locator) 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。简单的可以把URL理解为包含:协议、主机名、端口、路径、查询字符串和参数等对象。每一段可以独立设置。
做一个简单的Socket例子程序:
服务方:
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);
Socket client=server.accept();
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}
}
这个程序的主要目的在于服务器不断接收客户机所写入的信息只到,客户机发送"End"字符串就退出程序,并且服务器也会做出"Receive"为回应,告知客户机已接收到消息。
客户机代码:
import java.net.*;
import java.io.*;
public class Client{
static Socket server;
public static void main(String[] args)throws Exception{
server=new Socket(InetAddress.getLocalHost(),5678);
BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out=new PrintWriter(server.getOutputStream());
BufferedReader wt=new BufferedReader(new InputStreamReader(System.in));
while(true){
String str=wt.readLine();
out.println(str);
out.flush();
if(str.equals("end")){
break;
}
System.out.println(in.readLine());
}
server.close();
}
}
客户机代码则是接受客户键盘输入,并把该信息输出,然后输出"End"用来做退出标识。这个程序只是简单的两台计算机之间的通讯,如果是多个客户同时访问一个服务器呢?你可以试着再运行一个客户端,结果是会抛出异常的。那么多个客户端如何实现呢?
其实,简单的分析一下,就可以看出客户和服务通讯的主要通道就是Socket本身,而服务器通过accept方法就是同意和客户建立通讯.这样当客户建立Socket的同时。服务器也会使用这一根连线来先后通讯,那么既然如此只要我们存在多条连线就可以了。那么我们的程序可以变为如下:
服务器:
import java.io.*;
import java.net.*;
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);
while(true){
Socket client=server.accept();
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}
}
}
这里仅仅只是加了一个外层的While循环,这个循环的目的就是当一个客户进来就为它分配一个Socket直到这个客户完成一次和服务器的交互,这里也就是接受到客的"End"消息.那么现在就实现了多客户之间的交互了。但是.问题又来了,这样做虽然解决了多客户,可是是排队执行的。也就是说当一个客户和服务器完成一次通讯之后下一个客户才可以进来和服务器交互,无法做到同时服务,那么要如何才能同时达到既能相互之间交流又能同时交流呢?很显然这是一个并行执行的问题了。所以线程是最好的解决方案。
那么下面的问题是如何使用线程.首先要做的事情是创建线程并使得其可以和网络连线取得联系。然后由线程来执行刚才的操作,要创建线程要么直接继承Thread要么实现Runnable接口,要建立和Socket的联系只要传递引用就可以了.而要执行线程就必须重写run方法,而run方法所做的事情就是刚才单线程版本main所做的事情,因此我们的程序变成了这样:
import java.net.*;
import java.io.*;
public class MultiUser extends Thread{
private Socket client;
public MultiUser(Socket c){
this.client=c;
}
public void run(){
try{
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
//Mutil User but can't parallel
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}catch(IOException ex){
}finally{
}
}
public static void main(String[] args)throws IOException{
ServerSocket server=new ServerSocket(5678);
while(true){
//transfer location change Single User or Multi User
MultiUser mu=new MultiUser(server.accept());
mu.start();
}
}
}
我的类直接从Thread类继承了下来.并且通过构造函数传递引用和客户Socket建立了联系,这样每个线程就有了。一个通讯管道.同样我们可以填写run方法,把之前的操作交给线程来完成,这样多客户并行的Socket就建立起来了。
---------------------- <a href="http://edu.csdn.net/heima" target="blank">android培训</a>、<a href="http://edu.csdn.net/heima" target="blank">java培训</a>、期待与您交流! ----------------------
详细请查看:<a href="http://edu.csdn.net/heima" target="blank">http://edu.csdn.net/heima</a>