网络协议与TCP/IP:
本地回路的IP地址:127.0.0.1,网络程序传给它的内容,不经过网卡传递,直接被本地计算机的TCP/IP协议栈中上层协议接受,用于本地计算机使用的特殊IP地址。
端口号的范围为0~65535之间,0~1023之间的端口是用于一些知名的网络服务和应用
TCP/IP中又含有两个高级传输协议——>UDP和TCP:
TCP,传输控制协议(Transmission Control Protocal),是面向连接的通信协议。
UDP,用户数据报协议(User Datagram Protocal),是无连接通信协议。
Socket:
Socket是网络驱动层提供给应用程序编程的接口和一种机制。
Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和Port
JAVA中的网络编程类:
位于java.net包中
DataGramSocket类用于UDP通信。
ServerSocket类用于TCP通信的服务器端,是接受客户端数据连接的。
Socket类用于TCP通信的服务器端和客户端,是客户端/服务器之间数据传递和接受的连接。
UDP网络程序:
DatagramSocket类:
public
DatagramSocket();
public
DatagramSocket(int port);
public
DatagramSocket(int port,InetAddress laddr);
close()方法释放系统为之分配的资源
send(
DatagramSocket p
)用于发送UDP数据包。
receive(
DatagramSocket p
)用于接收UDP数据包。
DatagramPacket类:
public DatagramPacket(byte[] buf,int length)
public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
getInetAddres()和getPort()用来得到发送方的IP地址和端口号
getData()和getLength()用于返回字节数组缓冲区和它表示的长度。
InetAddress类:
用于表示计算机IP地址的一个类,而在日常应用中的计算机的IP地址是用“192.168.0.1”、“www.baidu.com”等字符串格式来表示的。
static InetAddress getByName(String host) 在给定主机名的情况下确定主机的 IP 地址。
String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。
用UDP编写网络聊天室:
public class Chat extends Frame {
List
lst
=
new
List(6);
TextField
tfIP
=
new
TextField(15);
TextField
tfData
=
new
TextField(20);
DatagramSocket
ds
=
null
;
public
Chat() {
try
{
ds
=
new
DatagramSocket(3000);
}
catch
(SocketException e1) {
//
TODO
Auto-generated catch block
e1.printStackTrace();
}
add(
lst
,
"Center"
);
Panel p =
new
Panel();
add(p,
"South"
);
p.setLayout(
new
BorderLayout());
p.add(
tfIP
,
"West"
);
p.add(
tfData
,
"East"
);
new
Thread(
new
Runnable() {
@Override
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() +
":"
+ dp.getPort(), 0);
}
catch
(IOException e) {
if
(!
ds
.isClosed()) {
e.printStackTrace();
}
}
}
}
}).start();
tfData
.addActionListener(
new
ActionListener() {
@Override
public
void
actionPerformed(ActionEvent e) {
byte
[] buf;
buf =
tfData
.getText().getBytes();
DatagramPacket dp;
try
{
dp =
new
DatagramPacket(buf, buf.
length
, InetAddress
.getByName(
tfIP
.getText()), 3000);
ds
.send(dp);
}
catch
(UnknownHostException e2) {
//
TODO
Auto-generated catch block
e2.printStackTrace();
}
catch
(IOException e3) {
//
TODO
Auto-generated catch block
e3.printStackTrace();
}
tfData
.setText(
""
);
}
});
addWindowListener(
new
WindowAdapter() {
@Override
public
void
windowClosing(WindowEvent e) {
ds
.close();
dispose();
System.exit(0);
}
});
}
public
static
void
main(String[] args) {
Chat chat =
new
Chat();
chat.setBounds(300, 300, 300, 300);
chat.setTitle(
"聊天室"
);
chat.setVisible(
true
);
chat.setResizable(
false
);
}
}
TCP网络程序:
TCP网络程序的工作原理:
(1)服务器程序创建一个ServerSocket,然后调用accept方法等待客户来连接。
(2)客户端程序创建一个Socket并请求与服务器建立连接。
(3)服务器接受客户的连接请求,并创建一个新的Socket与该客户建立专线连接。
(4)建立了连接的两个Socket在一个单独的线程(由服务器程序创建)上对话。
(5)服务器开始等待新的连接请求,当新的连接请求到达时,重复步骤(2)到步骤(5)的过程
ServerSocket类:
public ServerSocket()
public ServerSocket(int port)
public ServerSocket(int port,int backlog)
public ServerSocket(int port,int backlog,InetAddress bindAddr)
accept()
Socket
类:
public Socket()
public Socket(String host,int port)
public Socket(InetAddress address,int port)
public Socket(String host,int port,InetAddress localAddr,int localPort)
public Socket(
InetAddress address
,int port,InetAddress localAddr,int localPort)
getInputStream()和getOutputStream()方法
简单的TCP服务器程序:
public
class
TcpServer {
public
static
void
main(String[] args) {
try
{
ServerSocket ss =
new
ServerSocket(8001);
Socket s = ss.accept();
// 没有客户端请求的情况下一直处于阻塞状态
InputStream ips = s.getInputStream();
OutputStream ops = s.getOutputStream();
ops.write(
"welcome to our country"
.getBytes());
BufferedReader br=
new
BufferedReader(
new
InputStreamReader(ips));
br.readLine();
/*byte[] buff = new byte[1024];
int len = ips.read(buff);
System.out.println(new String(buff, 0, len));
*/
//ips.close();
br.close();
ops.close();
s.close();
ss.close();
//注意这4个资源关闭的顺序
}
catch
(IOException e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
}
完善的TCP服务器程序模型:
import java.io.IOException;
import
java.net.ServerSocket;
import
java.net.Socket;
//接收多个客户端的信息,并返回信息
public
class
ReverseServer {
public
static
void
main(String[] args) {
try
{
ServerSocket ss=
new
ServerSocket(8001);
boolean
bRunning=
true
;
while
(bRunning){
Socket s=ss.accept();
new
Thread(
new
Servicer(s)).start();
}
ss.close();
}
catch
(IOException e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
}
public class Servicer implements Runnable {
private Socket s;
public Servicer(Socket s) {
this.s = s;
}
@Override
public void run() {
while (true) {
try {
InputStream ips = s.getInputStream();
OutputStream ops = s.getOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(
ips));
PrintWriter pw = new PrintWriter(ops,true);
String strLine = br.readLine();
if (strLine.equalsIgnoreCase("quit")) {
break;
}
System.out.println(strLine+":"+strLine.length());
/*abd{backspace}c
c{backspace}dba*/
String strEcho = new StringBuffer(strLine).reverse().toString();
pw.println(strLine + "-->" + strEcho);
br.close();
pw.close();
s.close();
} catch (Exception e) {
// TODO: handle exception
} finally {
}
}
}
}
TCP客户端程序:
public class TcpClient {
public
static
void
main(String[] args) {
if
(args.
length
< 2) {
System.
out
.println(
"Usage:java TcpClient ServerIP ServerPort"
);
return
;
}
try
{
Socket s =
new
Socket(
/* InetAddress.getByAddress( */
args[0]
/* ) */
,
Integer.parseInt(args[1]));
InputStream ips = s.getInputStream();
OutputStream ops = s.getOutputStream();
BufferedReader brNet =
new
BufferedReader(
new
InputStreamReader(ips));
PrintWriter pw =
new
PrintWriter(ops);
BufferedReader keyBoard =
new
BufferedReader(
new
InputStreamReader(
System.
in
));
while
(
true
) {
String strWord = keyBoard.readLine();
if
(strWord.equalsIgnoreCase(
"quit"
)) {
break
;
}
System.
out
.println(brNet.readLine());
}
pw.close();
brNet.close();
keyBoard.close();
s.close();
}
catch
(NumberFormatException e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
catch
(UnknownHostException e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
catch
(IOException e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
}
通过TCP程序在网络上传递对象:
ObjectIputStream 和ObjectOutStream可以从底层输入流中读取对象类型的数据和将对象类型的数据写入到底层输出流。
使用ObjectInputStream和ObjectOutputStream来包装底层网络字节流,TCP服务器和TCP客户端之间就可以传递对象类型的数据。