- 浏览: 8377 次
- 性别:
- 来自: 上海
最新评论
目前较为流行的网络编程模型是
客户机/服务器(C/S)结构。即通信双方一方作为服务器等待客户提出请求并予以响应。客户则在需要服务时向服务器提出申请。服务器一般作为守护进程始终
运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也能及时得到服务。
8.1.2
网络基本概念
如:166.111.136.3 , 166.111.52.80
如:
www.tsinghua.edu.cn
www.fanso.com
端口号(port number):网络通信时同一机器上的不同进程的标识。
如:80,21,23,25,其中1~1024为系统保留的端口号
服务类型(service):网络的各种服务。
http, telnet, ftp, smtp
我们可以用以下的一幅图来描述这里我们所提到的几个概念:
8.1.3
两类传输协议:TCP;UDP
TCP是Tranfer Control
Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个
socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server
socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送
或接收操作。
使用UDP时,每个数据报中
都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。对于TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前必然要
建立连接,所以在TCP中多了一个连接建立的时间。
8.2 基于URL的高层次Java网络编程
8.2.2 URL的组成
协议名
(protocol)指明获取资源所使用的传输协议,如http、ftp、gopher、file等,资源名(resourceName)则应该是资源的
完整地址,包括主机名、端口号、文件名或文件内部的一个引用。例如:
http://www.sun.com/
协议名://主机名
http://home.netscape.com/home/welcome.html
协议名://机器名+文件名
http://www.gamelan.com:80/Gamelan/network.html#BOTTOM
协议名://机器名+端口号+文件名+内部引用
端口号是和Socket编程相关的一个概念,初学者不必在
此深究,在后面会有详细讲解。内部引用是HTML中的标记,有兴趣的读者可以参考有关HTML的书籍。
8.2.3 创建一个URL
为了表示URL, java.net中实现了类URL。我们可以通过下面的构造方法来初始化一个URL对象:
(1) public URL
(String spec);
通过一个表示URL地址的字符串可以构造一个URL对象。
URL
urlBase=new URL("
http://www
. 263.net/")
通过基URL和相对URL构造一个URL对象。
URL net263=new URL ("
http://www.263.net/
");
URL index263=new URL(net263, "index.html")
new URL("http", "
www.gamelan.com
", "/pages/Gamelan.net. html");
URL
gamelan=new URL("http", "
www.gamelan.com
", 80,
"Pages/Gamelan.network.html");
try{
URL myURL= new URL(…)
}catch
(MalformedURLException e){
…
//exception handler code here
…
}
一个URL对象生成后,其属性是不能被改变的,但是我们可以通过类URL所提供的方法来获取这
些属性:
public String getProtocol() 获取该URL的协议名。
public String
getHost() 获取该URL的主机名。
public int getPort()
获取该URL的端口号,如果没有设置端口,返回-1。
public String getFile() 获取该URL的文件名。
public String getRef() 获取该URL在文件中的相对位置。
public String getQuery()
获取该URL的查询信息。
public String getPath() 获取该URL的路径
public
String getAuthority() 获取该URL的权限信息
public String getUserInfo()
获得使用者的信息
public String getRef() 获得该URL的锚
下面的例子中,我们生成一个URL
对象,并获取它的各个属性。
import java.io.*;
public static void main (String [] args) throws
Exception{
URL tuto=new
URL(Aurl,"tutorial.intro.html#DOWNLOADING");
System.out.println("protocol="+ tuto.getProtocol());
System.out.println("host ="+ tuto.getHost());
System.out.println("filename="+ tuto.getFile());
System.out.println("port="+ tuto.getPort());
System.out.println("ref="+tuto.getRef());
System.out.println("query="+tuto.getQuery());
System.out.println("path="+tuto.getPath());
System.out.println("UserInfo="+tuto.getUserInfo());
System.out.println("Authority="+tuto.getAuthority());
}
}
protocol=http host =java.sun.com
filename=/docs/books/tutorial.intro.html
port=80
ref=DOWNLOADING
query=null
path=/docs/books/tutorial.intro.html
UserInfo=null
Authority=java.sun.com:80
8.2.5 从URL读取WWW网络资源
InputStream
openStream();
方法openSteam()与指定的URL建立连接并返回InputStream类的对象以从这一连
接中读取数据。
public class URLReader {
public static void
main(String[] args) throws Exception {
//声明抛出所
有例外
URL tirc = new URL("
http://www.tirc1.cs.tsinghua.edu.cn/
");
//构建一URL对象
BufferedReader
in = new BufferedReader(new InputStreamReader(tirc.openStream()));
//使用openStream得到一输入流并由此构造一个BufferedReader对象
String inputLine;
while ((inputLine = in.readLine()) != null)
//从输
入流不断的读数据,直到读完为止
System.out.println(inputLine); //把读入的数据打印到屏幕上
in.close(); //关闭输入流
}
}
URL netchinaren = new URL ("
http://edu.chinaren.com/index.shtml
");
URLConnectonn tc = netchinaren.openConnection();
}catch(MalformedURLException e){ //创建URL()对象失败
…
}catch
(IOException e){ //openConnection()失败
…
}
InputSteram getInputSteram();
OutputSteram getOutputStream();
URL url =new URL ("
http://www.javasoft.com/cgi-bin/backwards
");
//创建一URL对象
URLConnectin
con=url.openConnection();
//由URL对象获取URLConnection对象
DataInputStream dis=new DataInputStream (con.getInputSteam());
//由
URLConnection获取输入流,并构造DataInputStream对象
PrintStream ps=new
PrintSteam(con.getOutupSteam());
//由URLConnection获取输出流,并构造
PrintStream对象
String line=dis.readLine(); //从服务器读入一行
ps.println("client…"); //向服务器写出字符串 "client…"
其中backwards为服务器端
的CGI程序。实际上,类URL的方法openSteam()是通过URLConnection来实现的。它等价于
openConnection().getInputStream();
基于URL的网络编程在底层其实还是基于下面要讲的
Socket接口的。WWW,FTP等标准化的网络服务都是基于TCP协议的,所以本质上讲URL编程也是基于TCP的一种应用。
前面已经提到Socket通常用来实现C/S结构。
对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
(1) 创建Socket;
(2) 打开连接到Socket的输入/出流;
(3) 按照一定的协议对Socket进行读/写操作;
(4)
关闭Socket.
以上4个步骤是
针对TCP传输而言的,使用UDP进行传输时略有不同,在后面会有具体讲解。
Socket(InetAddress address, int port);
Socket(InetAddress address,
int port, boolean stream);
Socket(String host, int prot);
Socket(String host, int prot, boolean stream);
Socket(SocketImpl
impl)
Socket(String host, int port, InetAddress localAddr, int
localPort)
Socket(InetAddress address, int port, InetAddress
localAddr, int localPort)
ServerSocket(int port);
ServerSocket(int port, int backlog);
ServerSocket(int port, int
backlog, InetAddress bindAddr)
Socket client = new
Socket("127.0.01.", 80);
ServerSocket server = new
ServerSocket(80);
8.3.4 客户端的Socket
下面是一个典型的创建
客户端Socket的过程。
try{
Socket socket=new
Socket("127.0.0.1",4700);
//127.0.0.1是TCP/IP协议中默认的本机地址
}catch(IOException e){
System.out.println("Error:"+e);
}
8.3.5
服务器端的ServerSocket
下面是一个典型的创建Server端ServerSocket的过程。
ServerSocket server=null;
try {
server=new
ServerSocket(4700);
//创建一个ServerSocket在端口4700监听客户请求
}catch(IOException e){
System.out.println("can not listen to
:"+e);
}
Socket socket=null;
try {
socket=server.accept();
//accept()是一个阻塞的方法,一旦有客户请求,它就会返回一个Socket
对象用于同客户进行交互
}catch(IOException e){
System.out.println("Error:"+e);
}
8.3.6 打开输入/出流
类Socket提供了方法getInputStream
()和getOutStream()来得到对应的输入/输出流以进行读/写操作,这两个方法分别返回InputStream和OutputSteam类对
象。为了便于读/写数据,我们可以在返回的输入/输出流对象上建立过滤流,如DataInputStream、DataOutputStream或
PrintStream类对象,对于文本方式流对象,可以采用InputStreamReader和OutputStreamWriter、
PrintWirter等处理。
PrintStream os=new PrintStream(new
BufferedOutputStreem(socket.getOutputStream()));
DataInputStream
is=new DataInputStream(socket.getInputStream());
PrintWriter
out=new PrintWriter(socket.getOutStream(),true);
BufferedReader
in=new ButfferedReader(new InputSteramReader(Socket.getInputStream()));
8.3.7
关闭Socket
os.close();
is.close();
socket.close();
8.3.8
简单的Client/Server程序设计
1. 客户端程序
import java.net.*;
public class TalkClient {
public static
void main(String args[]) {
try{
Socket socket=new
Socket("127.0.0.1",4700);
//向本机的4700端口发出客户请求
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
PrintWriter os=new
PrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造
PrintWriter对象
BufferedReader is=new BufferedReader(new
InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入
流,并构造相应的BufferedReader对象
String readline;
readline=sin.readLine(); //从系统标准输入读入一字符串
while(!readline.equals("bye")){
//若从标准输入读入的字符串为 "bye"则停止循环
os.println(readline);
//将从系统标准输入读入的字符串输出到Server
os.flush();
//刷新输出流,使Server马上收到该字符串
System.out.println("Client:"+readline);
//在系统标准输出上打印读入的字符串
System.out.println("Server:"+is.readLine());
//从
Server读入一字符串,并打印到标准输出上
readline=sin.readLine();
//从系统标准输入读入一字符串
} //继续循环
os.close(); //关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
}catch(Exception e) {
System.out.println("Error"+e);
//出错,则打印出错信息
}
}
}
import java.net.*;
import java.applet.Applet;
public class
TalkServer{
public static void main(String args[]) {
try{
ServerSocket server=null;
try{
server=new ServerSocket(4700);
//创建一个ServerSocket在端口4700监听客户
请求
}catch(Exception e) {
System.out.println("can
not listen to:"+e);
//出错,打印出错信息
}
try{
socket=server.accept();
//使用accept()阻塞等待客户请求,有客户
//请求到来则产生一个Socket对象,并继续执行
}catch(Exception e) {
System.out.println("Error."+e);
//出错,打印出错信息
}
String line;
BufferedReader is=new BufferedReader(new
InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入
流,并构造相应的BufferedReader对象
PrintWriter
os=newPrintWriter(socket.getOutputStream());
//由Socket对象得到输出
流,并构造PrintWriter对象
BufferedReader sin=new BufferedReader(new
InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
//在标准输出上打印从客户端读
入的字符串
line=sin.readLine();
//从标准输入读入一字符串
while(!line.equals("bye")){
//如果该字符串为 "bye",则停止循环
os.println(line);
//向客户端输出该字符串
os.flush();
//刷新输出流,使Client马上收到该字符串
System.out.println("Server:"+line);
//在系统标准输出上打印读入的字符串
System.out.println("Client:"+is.readLine());
//从
Client读入一字符串,并打印到标准输出上
line=sin.readLine();
//从系统标准输入读入一字符串
} //继续循环
os.close();
//关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
server.close(); //关闭ServerSocket
}catch(Exception e){
System.out.println("Error:"+e);
//出错,打印出错信息
}
}
}
8.3.9 支持多客户的client/server程序设计
import
java.net.*;
public class MultiTalkClient {
public static void
main(String args[]) {
try{
Socket socket=new
Socket("127.0.0.1",4700);
//向本机的4700端口发出客户请求
BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
PrintWriter os=new
PrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并构造
PrintWriter对象
BufferedReader is=new BufferedReader(new
InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并
构造相应的BufferedReader对象
String readline;
readline=sin.readLine(); //从系统标准输入读入一字符串
while(!readline.equals("bye")){
//若从标准输入读入的字符串为 "bye"则停止循环
os.println(readline);
//将从系统标准输入读入的字符串输出到Server
os.flush();
//刷新输出流,使Server马上收到该字符串
System.out.println("Client:"+readline);
//在系统标准输出上打印读入的字符串
System.out.println("Server:"+is.readLine());
//从
Server读入一字符串,并打印到标准输出上
readline=sin.readLine();
//从系统标准输入读入一字符串
} //继续循环
os.close(); //关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
}catch(Exception e) {
System.out.println("Error"+e);
//出错,则打印出错信息
}
}
}
import java.net.*;
import ServerThread;
public class
MultiTalkServer{
static int clientnum=0; //静态成员变量,记录当前客户的个数
public static void main(String args[]) throws IOException {
ServerSocket serverSocket=null;
boolean listening=true;
try{
serverSocket=new ServerSocket(4700);
//创建一个
ServerSocket在端口4700监听客户请求
}catch(IOException e) {
System.out.println("Could not listen on port:4700.");
//出错,打印出
错信息
System.exit(-1); //退出
}
while(listening){
//永远循环监听
new
ServerThread(serverSocket.accept(),clientnum).start();
//监听到客户请
求,根据得到的Socket对象和
客户计数创建服务线程,并启动之
clientnum++;
//增加客户计数
}
serverSocket.close(); //关闭ServerSocket
}
}
import java.net.*;
public class
ServerThread extends Thread{
Socket socket=null;
//保存与本线程相关的Socket对象
int clientnum; //保存本进程的客户计数
public
ServerThread(Socket socket,int num) { //构造函数
this.socket=socket;
//初始化socket变量
clientnum=num+1; //初始化clientnum变量
}
public void run() { //线程主体
try{
String line;
BufferedReader is=new BufferedReader(new
InputStreamReader(socket.getInputStream()));
//由Socket对象得到输入流,并构造相应
的BufferedReader对象
PrintWriter
os=newPrintWriter(socket.getOutputStream());
//由Socket对象得到输出流,并
构造PrintWriter对象
BufferedReader sin=new BufferedReader(new
InputStreamReader(System.in));
//由系统标准输入设备构造BufferedReader对象
System.out.println("Client:"+ clientnum +is.readLine());
//在标准输出上打印从客户端读入的字符串
line=sin.readLine();
//从标准输入读入一字
符串
while(!line.equals("bye")){
//如果该字符串为 "bye",则停止循环
os.println(line);
//向客户端输出该字符串
os.flush();
//刷新输出流,使Client马上收到该字符串
System.out.println("Server:"+line);
//在系统标准输出上打印该字符串
System.out.println("Client:"+ clientnum +is.readLine());
//从Client读入一字符串,并打印到标准输出上
line=sin.readLine();
//
从系统标准输入读入一字符串
} //继续循环
os.close(); //关闭Socket输出流
is.close(); //关闭Socket输入流
socket.close(); //关闭Socket
server.close(); //关闭ServerSocket
}catch(Exception e){
System.out.println("Error:"+e);
//出错,打印出错信息
}
}
}
8.3.10
据报Datagram通讯
UDP,不可靠,差错控制开销较小,传输大小限制在64K以下,不需要建立连接。
8.3.12
Datagram通讯的表示方法:DatagramSocket;DatagramPacket
包java.net中提供了两个类
DatagramSocket和DatagramPacket用来支持数据报通信,DatagramSocket用于在程序之间建立传送数据报的通信连
接, DatagramPacket则用来表示一个数据报。先来看一下DatagramSocket的构造方法:
DatagramSocket();
DatagramSocket(int prot);
DatagramSocket(int port, InetAddress laddr)
其中,port指明socket所使
用的端口号,如果未指明端口号,则把socket连接到本地主机上一个可用的端口。laddr指明一个可用的本地地址。给出端口号时要保证不发生端口冲
突,否则会生成SocketException类例外。注意:上述的两个构造方法都声明抛弃非运行时例外SocketException,程序中必须进行
处理,或者捕获、或者声明抛弃。
DatagramPacket(byte buf[],int length);
DatagramPacket(byte
buf[], int length, InetAddress addr, int port);
DatagramPacket(byte[] buf, int offset, int length);
DatagramPacket(byte[] buf, int offset, int length, InetAddress address,
int port);
DatagramPacket packet=new DatagramPacket(buf, 256);
Socket.receive
(packet);
DatagramPacket packet=new DatagramPacket(buf,
length, address, port);
Socket.send(packet);
8.3.13
基于UDP的简单的Client/Server程序设计
import java.net.*;
import
java.util.*;
public class QuoteClient {
public static void
main(String[] args) throws IOException
{
if(args.length!=1) {
//如果启动的时候没有给出Server的名字,那么出错退出
System.out.println("Usage:java QuoteClient <hostname>");
//打印出错信息
return; //返回
}</hostname>
//创建数据报套接字
InetAddress address=InetAddress.getByName(args
[0]);
//由命令行给出的第一个参数默认为Server的名字,通过它得到Server的IP信息
DatagramPacket packet=new DatagramPacket (buf, buf.length, address,
4445);
//创建DatagramPacket对象
socket.send(packet); //发送
packet=new DatagramPacket(buf,buf.length);
//创建新的
DatagramPacket对象,用来接收数据报
socket.receive(packet); //接收
String received=new String(packet.getData());
//根据接收到的字节数组生成相应的字
符串
System.out.println("Quote of the Moment:"+received );
//打印生成的字符串
}
}
public static
void main(String args[]) throws java.io.IOException
{
new
QuoteServerThread().start();
//启动一个QuoteServerThread线程
}
}
import
java.net.*;
import java.util.*;
//服务器线程
public class
QuoteServerThread extends Thread
{
protected DatagramSocket
socket=null;
//记录和本对象相关联的DatagramSocket对象
protected
BufferedReader in=null;
//用来读文件的一个Reader
protected boolean
moreQuotes=true;
//标志变量,是否继续操作
//无参数的构造函数
this("QuoteServerThread");
//以QuoteServerThread为默认值调用带参数的构造函数
}
public
QuoteServerThread(String name) throws IOException {
super(name);
//调用父类的构造函数
socket=new DatagramSocket(4445);
//在端口4445创建数
据报套接字
try{
in= new BufferedReader(new FileReader("
one-liners.txt"));
//打开一个文件,构造相应的BufferReader对象
}catch(FileNotFoundException e) { //异常处理
System.err.println("Could not open quote file. Serving time instead.");
//打印出错信息
}
}
public void run() //线程主体
{
while(moreQuotes) {
try{
byte[] buf=new byte[256];
//创建缓冲区
DatagramPacket packet=new
DatagramPacket(buf,buf.length);
//由缓冲区构造DatagramPacket对象
socket.receive(packet); //接收数据报
String dString=null;
if(in= =null) dString=new Date().toString();
//如果初始化的时候
打开文件失败了,
//则使用日期作为要传送的字符串
else
dString=getNextQuote();
//否则调用成员函数从文件中读出字符串
buf=dString.getByte();
//把String转换成字节数组,以便传送
//从Client端传来的Packet中得到Client地址
int port=packet.getPort(); //和端口号
packet=new
DatagramPacket(buf,buf.length,address,port);
//根据客户端信息构建
DatagramPacket
socket.send(packet); //发送数据报
}catch(IOException e) { //异常处理
e.printStackTrace(); //打印错误栈
moreQuotes=false; //标志变量置false,以结束循环
}
}
socket.close(); //关闭数据报套接字
}
//成员函数,从文件中读数据
String returnValue=null;
try {
if((returnValue=in.readLine())= =null) {
//从文件中读一行,如果读到了文件尾
in.close( ); //关闭输入流
moreQuotes=false;
//标志变量
置false,以结束循环
returnValue="No more quotes. Goodbye.";
//置返回值
} //否则返回字符串即为从文件读出的字符串
}catch(IOEception e) {
//异常处理
returnValue="IOException occurred in server";
//置异常返回值
}
return returnValue; //返回字符串
}
}
8.3.14 用数据报进行广播通讯
import java.net.*;
import java.util.*;
public class
MulticastClient {
public static void main(String args[]) throws
IOException
{
MulticastSocket socket=new
MulticastSocket(4446);
//创建4446端口的广播套接字
InetAddress
address=InetAddress.getByName("230.0.0.1");
//得到230.0.0.1的地址信息
socket.joinGroup(address);
//使用joinGroup()将广播套接字绑定到地址上
DatagramPacket packet;
byte[]
buf=new byte[256];
//创建缓冲区
packet=new
DatagramPacket(buf,buf.length);
//创建接收数据报
socket.receive(packet); //接收
String received=new
String(packet.getData());
//由接收到的数据报得到字节数组,
//并由此构造
一个String对象
System.out.println("Quote of
theMoment:"+received);
//打印得到的字符串
} //循环5次
socket.
发表评论
相关推荐
java udp socket 网络编程
计算机网络socket编程,用Java程序实现UDP网络测试。
java网络编程包括socket tcp/udp io/nio讲解 http协议 jdbc rmi java的安全框架等知识
用java编写的基于UDP和TCP两种协议编写的Socket(网络编程)案列
socket的TCP与UDP编程示例
无论你是经验丰富的网络开发人员、Java程序员新手,还是只希望对Java网络编程稍有些了解的人,都会发现《Java编程(第三版)》将成为你的书库中一个重要的部分。一旦开始使用Java网络API,只要你能想到它就能够做...
java Udp 收发结构体实例 Socket编程 Udp收发大数据 单向传输 无需握手 广播 指定ip
Java网络编程精讲,主要涉及Socket,ServerSocket,NIO,http协议,tcp,udp精讲等等
通过j2se upd网络编程,发送报文。我这里只是客户端,修改数据库连接,主要是把数据库里面的图片(base64编码处理),拆成包,发送给服务端。
实现java使用套接字(socket)实现udp通信,有界面,可以实现单人,多人聊天,以及文件发送,里面含有服务器与客户端。
java网络开发,使用UDP协议进行通信,源代码可以直接运行,并且是可视化界面,方便大家学习
Java 网络编程 说明: 网络编程,分为两种一种是TCP、另一种是UDP方式。我们分别写一下TCP、UDP端的Server和Client简单演示代码。 TCP: Sever import java.io.DataInputStream; import java.io.IOException; ...
基于TCP和UDP的socket编程,给出了最简单的示例代码。 相关博文地址: http://blog.csdn.net/wintys/archive/2008/12/15/3525643.aspx http://blog.csdn.net/wintys/archive/2008/12/15/3525619.aspx
一,网络编程中两个主要的问题 二,两类传输协议:TCP;UDP 三,基于Socket的java网络编程
本书内容全面,涵盖了从网络基础知识到远程方法调用(RMI)等各方面的内容,书中章节涉及到TCP和UDPsocket、服务器socket、URL和URI、组播以及特殊用途的API(如JavaMail)等等。本书展示了如何使用JSSE编写安全的...
JAVA 简易的UDP协议Socket代码
Java_TCPIP_Socket经典网络编程 最好的java网络编程资料,现低分奉献. 目录: ...8 1.4 客户端和服务器.8 1.5 什么是套接字..........9 1.6 练习..........10 第2章基本套接字..........10 2.1 套接字地址.............
[奥莱理] Java 网络编程 第4版 (英文版) [奥莱理] Java Network Programming 4th Edition (E-Book) ☆ 图书概要:☆ This practical guide provides a complete introduction to developing network programs ...
Java中SocketJava中Socket编程编程,Socket实现tcp/udp,Sokcet实现单聊、群聊功能, 博客地址: https://blog.csdn.net/dreams_deng/article/details/105325640
关于java的网络编程的多个实例,Socket的用法,UDP,TCP协议的编程。