发布日期:2023-03-31来源:武汉北大青鸟武汉校区作者:武汉宏鹏
【网络协议定论:北大青鸟课程Java语言诠释TCP网络程序】网络就像密密麻麻的蜘蛛网,当然为了防止交通堵塞,人们就开始实行了一种类似于交通规则的网络协议。说到网络协议,就说到今天北大青鸟课程的主题——Java语言编写简单地TCP网络程序。在TCP/IP协议栈中,有两个协议,TCP(Transmission Control Protocol)和UDP(User Datagram Protocol),前者是面向连接的通信协议,后者是面向连接的通信协议。TCP/IP就是一个非常实用的网络协议,并且是网络应用程序的选协议。
两者数据包的基本格式如下:
数据收发过程示意图:
Java分别为UDP和TCP两种通信协议提供了相应的编程类,这些类存放在java.net包中,与UDP对应的是DatagramSocket,与TCP对应的是ServerSocket(服务器端)和Socket(客户端)。
下面我们分别简单介绍用Java编写简单UDP和TCP网络程序的基本方法。
一、用Java编写UDP网络程序
编写UDP网络程序,先用到DatagramSocket类和DatagramPacket类,前者好比创建的港口码头,后者好比我们发送和接收数据的集装箱。
下面是两个简单的UDP程序模型,读者应将程序中的这个地址修改成你的计算机的实际地址再编译运行。
发送程序:
import java.net.*;
public class UdpSend
{
public static void main(String [] args) throws Exception
{
DatagramSocket ds=new DatagramSocket();
String str="我的网络程序";
DatagramPacket dp=new DatagramPacket(str.getBytes
(),str.getBytes().length,
InetAddress.getByName("101.116.10.236"),3000);
ds.send(dp);
ds.close();
}
}
接收程序:
import java.net.*;
public class UdpRecv
{
public static void main(String [] args) throws Exception
{
DatagramSocket ds=new DatagramSocket(3000);
byte [] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,1024);
ds.receive(dp);
String strRecv=new String(dp.getData(),0,dp.getLength()) +
" from " + dp.getAddress().getHostAddress()+":"+dp.getPort();
System.out.println(strRecv);
ds.close();
}
}
下面是一个较为完善的UDP网络聊天程序,它包括gui以及发送和接收三个部分。
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class Chat
{
Frame f=new Frame("我的聊天室");
TextField tfIP=new TextField(15);
List lst=new List(6);
DatagramSocket ds;
/*由于DatagramSocket的构造函数声明可能抛出异常,我们的程序需要用try…catch语句
进行异常捕获处理,所以不能直接在这里调用DatagramSocket的构造函数对ds进行初始化,
我们需要将ds的初始化放在Chat类的构造函数中去完成。*/
public Chat()
{
try
{
ds=new DatagramSocket(3000);
}catch(Exception ex){ex.printStackTrace();}
new Thread(new Runnable()
{
public void run()
{
byte buf[]=new byte[1024];
DatagramPacket dp= new DatagramPacket(buf,1024);
while(true)
{
try
{
ds.receive(dp);
lst.add(new String(buf,0,dp.getLength())+
":from"+dp.getAddress().getHostAddress(),0);
}catch(Exception e){e.printStackTrace();}
}
}
}).start();
}
public static void main(String [] args)
{
Chat chat=new Chat();
chat.init();
}
public void init()
{
f.setSize(300,300);
f.add(lst);
Panel p=new Panel();
p.setLayout(new BorderLayout());
p.add("West",tfIP);
TextField tfData=new TextField(20);
p.add("East",tfData);
f.add("South",p);
f.setVisible(true);
f.setResizable(false);//限制用户改变窗口的大小
//增加关闭窗口的事件处理代码
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
ds.close();//程序退出时,关闭Socket,释放相关资源
f.setVisible(false);
f.dispose();
System.exit(0);
}
});
//增加在消息文本框中按下回车键的事件处理代码
tfData.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//取出文本框中的消息字符串,并将其转换成字节数组
byte[] buf;
buf = e.getActionCommand().getBytes();
try
{
DatagramPacket dp= new DatagramPacket(buf,buf.length,
InetAddress.getByName(tfIP.getText()),3000);
ds.send(dp);
}catch(Exception ex){ex.printStackTrace();}
/*上面的Exception的引用变量名不能为e,而是改写成了ex,因为e已经在
actionPerformed方法中作为形式参数变量名被定义过了。*/
((TextField)e.getSource()).setText("");
}
});
}
}
二、用Java编写TCP网络程序
与UDP协议不同, 利用TCP协议通信的两个程序是有主次之分的,一个是服务器程序,一个是客户机程序,其交互过程如图:
下面这两个程序是TCP协议程序的基本框架和雏形。
服务器端:
import java.net.*;
import java.io.*;
class Servicer implements Runnable
{
Socket s;
public Servicer(Socket s)
{
this.s = s;
}
public void run()
{
try
{
InputStream ips=s.getInputStream();
OutputStream ops=s.getOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(ips));
DataOutputStream dos = new DataOutputStream(ops);
while(true)
{
String strWord = br.readLine();
//System.out.println(strWord +":" + strWord.length());
if(strWord. equalsIgnoreCase("quit"))
break;
String strEcho = (new StringBuffer(strWord).reverse()).toString();
//dos.writeBytes(strWord +"---->"+ strEcho +"\r\n");
dos.writeBytes(strWord + "---->"+ strEcho +
System.getProperty("line.separator")); }
br.close();
//关闭包装类,会自动关闭包装类中所包装的底层类。所以不用调用ips.close()
dos.close();
s.close();
}catch(Exception e){e.printStackTrace();}
}
}
class TcpServer
{
public static void main(String [] args)
{
try
{
/*ServerSocket ss=null;
if(args.length<1)
ss=new ServerSocket(8001);
else
ss=new ServerSocket(Integer.parseInt(args[0]));*/
ServerSocket ss=new ServerSocket(8001);
while(true)
{
Socket s=ss.accept();
new Thread(new Servicer(s)).start();
}
//ss.close();
}catch(Exception e){e.printStackTrace();}
}
}
客户端:
import java.net.*;
import java.io.*;
public class TcpClient
{
public static void main(String [] args)
{
try
{
//Socket s=new Socket(InetAddress.getByName
("192.168.0.223"),8001);
if(args.length < 2)
{
System.out.println("Usage:java TcpClient ServerIP
ServerPort");
return;
}
Socket s=new Socket(
InetAddress.getByName(args[0]),Integer.parseInt(args[1]));
InputStream ips=s.getInputStream();
OutputStream ops=s.getOutputStream();
BufferedReader brKey =
new BufferedReader(new InputStreamReader(System.in));
DataOutputStream dos = new DataOutputStream(ops);
BufferedReader brNet = new BufferedReader(new
InputStreamReader(ips));
while(true)
{
String strWord = brKey.readLine();
dos.writeBytes(strWord + System.getProperty
("line.separator"));
if(strWord.equalsIgnoreCase("quit"))
break;
else
System.out.println(brNet.readLine());
}
dos.close();
brNet.close();
brKey.close();
s.close();
}catch(Exception e){e.printStackTrace();}
}
}
在今天的课程学习中,我们收获了如何用Java语言编写简单的TCP网络程序,后北大青鸟光谷校区的小编还是提醒各位,程序中的ip地址要改为你的计算机的ip地址后再编译运行。
Copyright (c) 2006-2023 武汉宏鹏教育咨询有限公司 版权所有 All Rights Reserved.