10. TCP协议和UDP协议TCP(transmission control protocol)
是专门设计用于在不可靠的因特网上提供可靠的、端到端的字节流通信的协议。它是一种面向连接的协议。TCP连接是字节流而非报文流。
UDP(user data protocol)
UDP向应用程序提供了一种发送封装的原始IP数据报的方法,并且发送时无需建立连接。是一种不可靠的连接 .
19. Java实例——(续) // step 3 and 4. Get an InputStream and encapsulate it
BufferedReader in = new BufferedReader(new
InputStreamReader(connection.getInputStream()));
// print first ten lines of contents
String line = null;
n = 1;
// step 5. Read info from the stream
while ((line = in.readLine()) != null && n <= 10){
System.out.println(line);
n++;
}
if (line != null)
System.out.println(". . .");
}
catch (IOException exception){
exception.printStackTrace();
}
}
}
20. Socket通信两个Java应用程序可通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket。
Socket通常用来实现client-server连接。
java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向连接的client和server端
建立连接时所需的寻址信息为远程计算机的IP地址和端口号(Port number)
A socket is bound to a port number so that the TCP layer can identify the application that data is destined to be sentServerClientportConnection
requestServerClientportConnectionport
21. Socket 通信模型ServerServerSocket s(port #)s.accept() / 等待连接Socket 对象OutputStreamInputStreamsocket.close()ClientSocket (host, port #)
(Attempt to connect)OutputStreamInputStreamsocket.close()
22. Typical Steps to Write a Socket ServerCreate a serversocket
Accept a connection request from a client and return a new socket
Get input stream / output stream from the accpeted socket
Encapsulate raw input stream /output stream to high level streams according to data type (optional)
Receive/send message from/to streams
Release resources ServerSocket(port)Socket.getInputStream()/
Socket.getOuputStream()DataInputStream(InputStream) /
DataOutputStream(OutputStream)
(for example, optional)(XXX)InputStream.read() /
(XXX)OutputStream.write()(XXX)InputStream.close() /
(XXX)OutputStream.close()
Socket.close(),
ServerSocket.close()Socket s = ServerSocket.accept()
23. A ServerSocket Sample—Daytime ServerThe daytime server based on TCP listens on port 13, it accepts connection request from a client and generate a new socket.
Get a OutputStream from the new socket and encapsulate it to a PrintWriter
Prepare the daytime string and write it to the PrintWriter
Close resources including PrintWriter, Socket and ServerSocket
24. ServerSocketimport java.net.*;
import java.io.*;
import java.util.*;
import java.text.SimpleDateFormat;
public class DaytimeServer {
public static void main(String[] args) {
ServerSocket ss = null;
Socket s = null;
PrintWriter pw = null;
try {
// step 1. Create a listen socket
ss = new ServerSocket(8899);
// step 2. Accept connection request from a client
s = ss.accept();
// step 3. Get a OutputStream from the socket
OutputStream os = s.getOutputStream();
// step 4. Encapsulate os to a PrintWriter
pw = new PrintWriter(os);
SimpleDateFormat format = new SimpleDateFormat
("yyyy-MM-ddhh:mm:ss");
27. Steps to Write a Socket ClientCreate a socket
Get input stream and/or output stream from the connected socket
Encapsulate raw input stream /output stream to high level streams according to data type (optional)
Receive/send message from/to streams
Release resources Socket(host, port)Socket.getInputStream()/
Socket.getOuputStream()DataInputStream(InputStream) /
DataOutputStream(OutputStream)
(for example, optional)(XXX)InputStream.read() /
(XXX)OutputStream.write()(XXX)InputStream.close() /
(XXX)OutputStream.close()
Socket.close()
28. A Socket Client—Getting Daytime from A ServerMost unix systems provide daytime service based on TCP protocol on port 13. The daytime server accept a client connection request and send back the daytime string followed by a new line character to the client, then close the connection.
So, we create a socket to connect to the daytime server, encapsulate the input stream got from Socket to a BufferedReader, read one line of string from the BufferedReader and display the string, then release all resources.
29. A Socket Client—Getting Daytime from A Server(Cont.)import java.net.Socket;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
public class TimeClient {
public static void main(String[] args) {
// The program needs a command line argment to specify the name
// or IP address of a daytime server
if (args.length != 1) {
System.out.println("Usage: " + "java " +TimeClient.class.getName()+ " timeServerName");
System.exit(1);
}
30. A Socket Client—Getting Daytime from A Server(Cont.) Socket s = null;
BufferedReader br = null; // Encapsulate the InputStream got from s
try {
// step 1. Create a socket
s = new Socket(args[0], 8899);
// step 2. Get an InputStream from the socket
InputStream is = s.getInputStream();
// step 3. Encapsulate the InputStream to a BufferedReader
br = new BufferedReader(new InputStreamReader(is));
// step 4. Read the daytime string from the reader
String str = br.readLine();
System.out.println(str);
33. Steps to Handle Concurrency in Socket Server ProgrammingMultiple clients access a server at the same time, each client needs a connection, so one thread per connection
Create a server socket
Accept a connection request from a client and return a new socket, then generate a service thread (repeat)
In thread get input stream / output stream from the accpeted socket
In thread encapsulate raw input stream /output stream to high level streams according to data type (optional)
In thread receive/send message from/to streams
In thread Release resources ThreadSeverSocket(port)Socket.getInputStream()/
Socket.getOuputStream()DataInputStream(InputStream) /
DataOutputStream(OutputStream)
(for example, optional)(XXX)InputStream.read() /
(XXX)OutputStream.write()(XXX)InputStream.close() /
(XXX)OutputStream.close()
Socket.close(),
ServerSocket.close()Socket s = SeverSocket.accept()
34. A Multi-Thread ServerSocket Sample— Reversioned Daytime ServerThe daytime server based on TCP listens on port 13, it accepts connection request from a client and generate a new socket.
Fork a new thread and pass the new socket to the thread
In the thread get a OutputStream from the new socket and encapsulate it to a PrintWriter
In the thread prepare the daytime string and write it to the PrintWriter
In the thread close resources including PrintWriter, Socket
35. ThreadServerimport java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;
public class ThreadServer extends Thread {
private Socket s;
public ThreadServer(Socket s) {
this.s = s;
}
public void run() {
PrintWriter pw = null;
try { // step 1. Get a OutputStream from the socket
OutputStream os = s.getOutputStream();
// step 2. Encapsulate os to a PrintWriter
pw = new PrintWriter(os);
37. DaytimeServer2import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
public class DaytimeServer2 {
public static void main(String[] args) {
ServerSocket ss = null;
Socket s = null; // store the return from ss.accept()
try {
// step 1. Create a listen socket
ss = new ServerSocket(13);
// step 2. Accept connection request from a client
while (true) {
s = ss.accept();
new ThreadServer(s).start();
}
} catch (IOException e) { e.printStackTrace();
} finally {
try { ss.close();
} catch (IOException e) { }
}
}
}
38. UDP UDP通信是一种无连接的数据报通信,采用数据报通信协议UDP(User Datagram Protocol)。按照这个协议,两个系统在进行通信时,不要建立连接,优点是它发送数据的速度很快,而缺点是数据较易丢失,例如我们使用的红外线数据传输就是采用UDP的传输协议。
Connectionless protocol
Not reliable transfer
DatagramSocket and DatagramPacket support Java UDP
39. java.net.DatagramPacket数据报包用来实现无连接包投递服务。
每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。
Constructors
DatagramPacket(byte[] buf, int length):
构造 DatagramPacket,用来接收长度为 length 的数据包, length 参数必须小于或等于 buf.length
DatagramPacket(byte[] buf, int length, InetAddress address, int port):构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。length 参数必须小于或等于 buf.length。
Methods
getAddress()/getSockAddress()/getPort()
setAddress()/setSockAddress()/setPort()
40. java.net.DatagramSocketA datagram socket is the sending or receiving point for a packet delivery service
Constructors
DatagramSocket(int port)
Methods
connect()/close()
receive()/send()
41. Typical Steps to Write a UDP ServerCreate a DatagramSocket bound to a port
Prepare a datagram packet to receive message from clients
Receive message on datagram socket and put the message into datagram packet
Get the info of the client protocol address
Prepare a datagram packet which includes message sent back to the client
Send datagram packet to the client
Repeat 2 - 6
DatagramSocket(port)DatagramSocket.
receive(DatagramPacket)DatagramPacket.getAddress();
DatagramPacket.getPort()DatagramPacket(buffer, length,
clientAddress, clientPort);DatagramSocket.send
(Datagrampacket)DatagramPacket(buffer, len);
42. A UDP Server Sample—Daytime ServerThe daytime server based on UDP bound to port 13, it must receive message from a client first because it has no sense of the protocol address info of a client
So, a client can send any message to the server because the server ignore it
The server get address info from the inbound datagram packet
Prepare the daytime string and put it in the outbound datagram packet
Send the outbound datagram packet from the datagram socket to the client
43. UDPDaytimeServerimport java.io.*;
import java.net.*;
import java.util.*;
public class UDPDaytimeServer {
public static void main(String args[]) {
UDPDaytimeServer udpServer = new UDPDaytimeServer();
try {
udpServer.go();
} catch (IOException e) {
System.out.println("IOException occured with socket.");
System.out.println(e);
System.exit(1);
}
}
// This method retrieves the current time on the server
public byte[] getTime() {
Date d = new Date();
return d.toString().getBytes();
}
44. UDPDaytimeServer // Main server loop.
public void go() throws IOException {
DatagramSocket datagramSocket;
DatagramPacket inDataPacket;
// Datagram packet from the client
DatagramPacket outDataPacket;
// Datagram packet to the client
InetAddress clientAddress; // Client return address
int clientPort; // Client return port
byte[] msg = new byte[10]; // Incoming data buffer. Ignored.
byte[] time; // Stores retrieved time
// Allocate a socket to man port 13 for requests.
datagramSocket = new DatagramSocket(13);
System.out.println("UDP server active on port 13");
// Loop forever
while (true) {
45. UDPDaytimeServer // Set up receiver packet. Data will be ignored.
inDataPacket = new DatagramPacket(msg, msg.length);
// Get the message.
datagramSocket.receive(inDataPacket);
// Retrieve return address information, including InetAddress
// and port from the datagram packet just recieved.
clientAddress = inDataPacket.getAddress();
clientPort = inDataPacket.getPort();
// Get the current time.
time = getTime();
// set up a datagram to be sent to the client using the
// current time, the client address and port
outDataPacket = new DatagramPacket(time, time.length,
clientAddress, clientPort);
// finally send the packet
datagramSocket.send(outDataPacket);
}
}
}
46. Typical Steps to Write a UDP ClientCreate a datagram socket
Prepare a datagram packet which includes message and the server protocol address info
Send the datagram packet to the server from the datagram socket
Prepare a datagram socket which includes a buffer and its length to receive response from the server
Receive message from the datagram socket and put the message into the datagram packet prepared in the last step
Close the datagram socketDatagramSocket()DatagramSocket.
send(DatagramPacket)DatagramPacket(buffer, length)DatagramSocket.receive
(Datagrampacket)DatagramSocket.close()DatagramPacket(buffer, len,
Serveraddr, serverport);
47. A UDP Client Sample— Daytime ClientThe daytime client based on UDP get the daytime string from a udp daytime server bound to port 13
First the client prepare a outbound datagram packet which includes the server protocol address info and a buffer
Send the outbound datagram packet to the server
Prepare an inbound datagram packet in which there is a buffer to holds daytime string sent back from the server
Receive message from the datagram socket and put the message into the inboud datagram packet
48. UDPClientimport java.io.*;
import java.net.*;
public class UDPClient {
public static void main(String args[]) {
UDPClient udpClient = new UDPClient();
try {
udpClient.go();
} catch (Exception e) {
System.out.println("Exception occured with socket.");
System.out.println(e);
System.exit(1);
}
}
public void go() throws IOException, UnknownHostException {
DatagramSocket datagramSocket;
DatagramPacket outDataPacket;
// Datagram packet to the server
DatagramPacket inDataPacket;
// Datagram packet from the server
InetAddress serverAddress; // Server host address
byte[] msg = new byte[100]; // Buffer space.
49. UDPClient String receivedMsg;
// Received message in String form.
// Allocate a socket by which messages are sent and received.
datagramSocket = new DatagramSocket();
// Server is running on this same machine for this example.
// This method can throw an UnknownHostException.
serverAddress = InetAddress.getLocalHost();
// Set up a datagram request to be sent to the server.
// Send to port 13
outDataPacket = new DatagramPacket(msg, 1, serverAddress, 13);
// Make the request to the server.
datagramSocket.send(outDataPacket);
// Set up a datagram packet to receive server's response.
inDataPacket = new DatagramPacket(msg, msg.length);
// Receive the time data from the server
datagramSocket.receive(inDataPacket);
// Print the data received from the server
ReceivedMsg = new String(inDataPacket.getData(), 0, inDataPacket.getLength());
System.out.println(receivedMsg);
// close the socket
DatagramSocket.close();
}}