当前位置: 技术问答>java相关
110分:JAVA中Socket如何发送和接收字节数组?
来源: 互联网 发布时间:2015-03-16
本文导语: | 我的省略了的部分参考: import java.io.*; import java.net.*; import java.sql.*; import java.util.Vector; class ServerThread extends Thread{//继承线程 private Socket socket;//定义套接口 private BufferedReader in;//定义输入流 private PrintWrite...
|
我的省略了的部分参考:
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.Vector;
class ServerThread extends Thread{//继承线程
private Socket socket;//定义套接口
private BufferedReader in;//定义输入流
private PrintWriter out;//定义输出流
int no;//
public ServerThread(Socket s) throws IOException {//线程构造函数
socket=s;//取得传递参数
in=new BufferedReader(new InputStreamReader(socket.getInputStream()));//创建输入流
out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);//创建输出流
start();//启动线程
}
public void run(){//线程监听函数
try{ while(true){
String str=in.readLine();//取得输入字符串
if(str.equals("end"))break;//如果是结束就关闭连接
//***************************
}
public class Server{//主服务器类
public static void main(String args[])throws IOException{
ServerSocket s=new ServerSocket(8080);//在8080端口创建套接口
System.out.println("Server start.."+s);
try{
while(true){Socket socket=s.accept();//无限监听客户的请求
System.out.println("Connectino accept:"+socket);
try{new ServerThread(socket);//创建新线程
}catch(IOException e){socket.close();}
}
}finally{s.close();}//捕或异常
}
}//服务器程序结束
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.Vector;
class ServerThread extends Thread{//继承线程
private Socket socket;//定义套接口
private BufferedReader in;//定义输入流
private PrintWriter out;//定义输出流
int no;//
public ServerThread(Socket s) throws IOException {//线程构造函数
socket=s;//取得传递参数
in=new BufferedReader(new InputStreamReader(socket.getInputStream()));//创建输入流
out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);//创建输出流
start();//启动线程
}
public void run(){//线程监听函数
try{ while(true){
String str=in.readLine();//取得输入字符串
if(str.equals("end"))break;//如果是结束就关闭连接
//***************************
}
public class Server{//主服务器类
public static void main(String args[])throws IOException{
ServerSocket s=new ServerSocket(8080);//在8080端口创建套接口
System.out.println("Server start.."+s);
try{
while(true){Socket socket=s.accept();//无限监听客户的请求
System.out.println("Connectino accept:"+socket);
try{new ServerThread(socket);//创建新线程
}catch(IOException e){socket.close();}
}
}finally{s.close();}//捕或异常
}
}//服务器程序结束
|
Objects and Java Seminar by Bill Venners
Network Programming
Lecture Handout
--------------------------------------------------------------------------------
Seminars | Objects & Java | Design Workshop | Jini & Distrib | Objects & Patterns | Modules
Agenda
Introduce network programming, IP, and sockets
Give a client/server code example
Compare TCP and UDP
Introduce datagrams and give a code example
Touch on multicast protocol
Introduce URLs and give a code example
--------------------------------------------------------------------------------
Network Programming
Java's architecture is network-oriented.
The java.net library simplifies network programming.
You use Java I/O streams to communicate via sockets.
Java's built-in support for multi-threading simplifies creating server programs that must handle multiple client requests concurrently.
--------------------------------------------------------------------------------
IP and Sockets
IP (internet protocol) breaks communication into packets.
Packets routed and delivered separately
No delivery guarantee
Max packet size: 65535 (less a 20 byte header)
Sockets enable two machines to communicate via IP.
Other protocols layered on top of IP:
TCP (Transmission Control Protocol)
UDP (User Datagram Protocol)
--------------------------------------------------------------------------------
IP Addresses
IP requires that each machine have a unique IP address.
Represented by the InetAddress class of java.net.
IP Addresses are 32-bit numbers, often represented in these two forms:
host name (A DNS name such as artima.com)
quad form (205.73.4.217)
InetAddress.getByName(String) does DNS lookup (or reverse lookup) and returns an InetAddress object.
--------------------------------------------------------------------------------
Client/Server Computing
A socket connects a client and a server.
The server listens on a port for client requests.
Clients must specify the server's host IP Address and port number to make the request.
Once connected, the client/server distinction goes away from the sockets' perspective.
--------------------------------------------------------------------------------
Port Number
Port numbers are 16-bit unsigned integers (represented in Java by int's).
Each port represents a "service" offered by the host.
Ports 0 - 1024 are reserved for well-known services.
You should use parts above 1024 for your own servers.
Clients must specify both port and IP Address when making a connection request.
--------------------------------------------------------------------------------
Localhost
The reserved host name "localhost" allows you to test a network program without a network.
Server and clients can all exist on the same computer.
Three ways to get an InetAddress object for localhost:
InetAddress.getByName(null);
InetAddress.getByName("localhost");
InetAddress.getByName("127.0.0.1");
--------------------------------------------------------------------------------
The Summer Server Application
1 // In file network/ex1/SummerServer.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.StringTokenizer;
5
6 public class SummerServer {
7
8 public static final int PORT = 2000;
9
10 private static class InvalidLongException
11 extends Exception {
12
13 private String message;
14
15 InvalidLongException(String s) {
16 message = s;
17 }
18
19 public String getMessage() {
20 return message;
21 }
22 }
23
24 public static void main(String[] args)
25 throws IOException {
26
27 ServerSocket listener =
28 new ServerSocket(PORT);
29
30 try {
31
32 for (;;) {
33
34 Socket sock = listener.accept();
35
36 try {
37
38 serveClient(sock);
39 }
40 finally {
41 sock.close();
42 }
43 }
44 }
45 finally {
46 listener.close();
47 }
48 }
49
50 private static void serveClient(Socket sock)
51 throws IOException {
52
53 BufferedReader reader = new BufferedReader(
54 new InputStreamReader(
55 sock.getInputStream()));
56
57 BufferedWriter writer = new BufferedWriter(
58 new OutputStreamWriter(
59 sock.getOutputStream()));
60
61 for (;;) {
62
63 String s = reader.readLine();
64
65 if (s == null) {
66 break;
67 }
68
69 String outString;
70 try {
71 outString =
72 Long.toString(sumString(s));
73 }
74 catch(InvalidLongException e) {
75 outString = e.getMessage();
76 }
77 writer.write(outString);
78 writer.newLine();
79 writer.flush();
80 }
81 }
82
83 private static long sumString(String s)
84 throws InvalidLongException {
85
86 long sum = 0;
87
88 StringTokenizer st = new StringTokenizer(s);
89 String token;
90 while (st.hasMoreTokens()) {
91 token = st.nextToken();
92 try {
93 sum += Long.parseLong(token);
94 }
95 catch (NumberFormatException e) {
96 throw new InvalidLongException(
97 "Invalid number: " + token);
98 }
99 }
100
101 return sum;
102 }
103 }
104
1 // In file network/ex1/SummerClient.java
2 import java.net.*;
3 import java.io.*;
4
5 public class SummerClient {
6
7 public static void main(String[] args)
8 throws IOException {
9
10 InetAddress ia = InetAddress.getByName(null);
11
12 Socket sock = new Socket(ia, SummerServer.PORT);
13
14 try {
15
16 BufferedReader serverReader =
17 new BufferedReader(
18 new InputStreamReader(
19 sock.getInputStream()));
20
21 BufferedWriter serverWriter =
22 new BufferedWriter(
23 new OutputStreamWriter(
24 sock.getOutputStream()));
25
26 LineNumberReader stdinReader =
27 new LineNumberReader(
28 new BufferedReader(
29 new InputStreamReader(
30 System.in)));
31
32 for (;;) {
33
34 String userLine = stdinReader.readLine();
35
36 if (userLine == null ||
37 userLine.length() == 0) {
38
39 break;
40 }
41
42 serverWriter.write(userLine);
43 serverWriter.newLine();
44 serverWriter.flush();
45
46 String serverLine = serverReader.readLine();
47 System.out.println(serverLine);
48 }
49 }
50 finally {
51 sock.close();
52 }
53 }
54 }
55
--------------------------------------------------------------------------------
Handling Multiple Clients Concurrently
1 // In file network/ex2/SummerServer.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.StringTokenizer;
5
6 public class SummerServer {
7
8 public static final int PORT = 2000;
9
10 private static class InvalidLongException
11 extends Exception {
12
13 private String message;
14
15 InvalidLongException(String s) {
16 message = s;
17 }
18
19 public String getMessage() {
20 return message;
21 }
22 }
23
24 private static class SummerService
25 extends Thread {
26
27 private Socket sock;
28
29 public SummerService(Socket sock) {
30 this.sock = sock;
31 }
32
33 public void run() {
34
35 try {
36
37 BufferedReader reader =
38 new BufferedReader(
39 new InputStreamReader(
40 sock.getInputStream()));
41
42 BufferedWriter writer =
43 new BufferedWriter(
44 new OutputStreamWriter(
45 sock.getOutputStream()));
46
47 for (;;) {
48
49 String s = reader.readLine();
50
51 if (s == null) {
52 break;
53 }
54
55 String outString;
56 try {
57 outString =
58 Long.toString(sumString(s));
59 }
60 catch(InvalidLongException e) {
61 outString = e.getMessage();
62 }
63 writer.write(outString);
64 writer.newLine();
65 writer.flush();
66 }
67 }
68 catch (IOException e) {
69 }
70 finally {
71 try {
72 sock.close();
73 }
74 catch (IOException e) {
75 }
76 }
77 }
78 }
79
80 public static void main(String[] args)
81 throws IOException {
82
83 ServerSocket listener = new ServerSocket(PORT);
84
85 try {
86
87 for (;;) {
88
89 Socket sock = listener.accept();
90
91 SummerService ss =
92 new SummerService(sock);
93 ss.start();
94 }
95 }
96 finally {
97 listener.close();
98 }
99 }
100
101 private static long sumString(String s)
102 throws InvalidLongException {
103
104 long sum = 0;
105
106 StringTokenizer st = new StringTokenizer(s);
107 String token;
108 while (st.hasMoreTokens()) {
109 token = st.nextToken();
110 try {
111 sum += Long.parseLong(token);
112 }
113 catch (NumberFormatException e) {
114 throw new InvalidLongException(
115 "Invalid number: " + token);
116 }
117 }
118
119 return sum;
120 }
121 }
122
1 // In file network/ex2/SummerClient.java
2 import java.net.*;
3 import java.io.*;
4
5 public class SummerClient {
6
7 public static void main(String[] args)
8 throws IOException {
9
10 InetAddress ia = InetAddress.getByName(null);
11
12 Socket sock = new Socket(ia,
13 SummerServer.PORT);
14
15 try {
16
17 BufferedReader serverReader =
18 new BufferedReader(
19 new InputStreamReader(
20 sock.getInputStream()));
21
22 BufferedWriter serverWriter =
23 new BufferedWriter(
24 new OutputStreamWriter(
25 sock.getOutputStream()));
26
27 LineNumberReader stdinReader =
28 new LineNumberReader(
29 new BufferedReader(
30 new InputStreamReader(
31 System.in)));
32
33 for (;;) {
34
35 String userLine =
36 stdinReader.readLine();
37
38 if (userLine == null ||
39 userLine.length() == 0) {
40
41 break;
42 }
43
44 serverWriter.write(userLine);
45 serverWriter.newLine();
46 serverWriter.flush();
47
48 String serverLine =
49 serverReader.readLine();
50 System.out.println(serverLine);
51 }
52 }
53 finally {
54 sock.close();
55 }
56 }
57 }
58
--------------------------------------------------------------------------------
TCP versus UDP
The Summer Server examples use TCP.
TCP (Transmission Control Protocol):
"reliable" (the packets are guaranteed to get there)
packets arrive in the order they were sent
slower than UDP (reliability has overhead)
UDP (User Data Protocol):
"unreliable" (the packets aren't guaranteed to get there)
packets may arrive out of order
packets may arrive faster than they can be consumed
faster than TCP (because less overhead)
--------------------------------------------------------------------------------
Datagrams
Datagrams (UDP packets) are like letters:
You put the recipient's and your own return address (IP Address & Port Number) on the envelope.
You send it, but don't know if whether it will actually get there.
If you send a second letter tomorrow, that might get there first.
UDP is used for:
Clock tickers, game player position announcers, etc...
Streaming protocals such as RealAudio
Designing a faster reliable protocol than TCP
--------------------------------------------------------------------------------
Using Datagrams
Need a DatagramSocket on both client and server.
To send, place the data (up to 65535 bytes less 20-byte header) into a DatagramPacket.
On receiving end, get a DatagramPacket containing the data.
There is no "connection" as with TCP.
--------------------------------------------------------------------------------
The Clock Server
1 // In file network/ex3/ClockServer.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.StringTokenizer;
5 import java.util.Vector;
6 import java.util.Date;
7
8 public class ClockServer {
9
10 public static final int REGISTRATION_PORT = 2001;
11 private final static int ADDR_BYTE_SIZE = 4;
12
13 private Vector mailingList = new Vector();
14
15 public static class AddressAndPort
16 implements Serializable {
17
18 private InetAddress addr;
19 private int port;
20
21 public AddressAndPort(InetAddress addr, int port) {
22
23 this.addr = addr;
24 this.port = port;
25 }
26
27 public InetAddress getAddress() {
28 return addr;
29 }
30
31 public int getPort() {
32 return port;
33 }
34
35 public boolean equals(Object o) {
36
37 if (o == null) {
38 return false;
39 }
40
41 AddressAndPort anp;
42
43 try {
44 anp = (AddressAndPort) o;
45 }
46 catch (ClassCastException e) {
47 return false;
48 }
49
50 if (addr.equals(anp.addr) && port == anp.port) {
51 return true;
52 }
53 else {
54 return false;
55 }
56 }
57 }
58
59 private class RegistrationService extends Thread {
60
61 private Socket sock;
62
63 public void run() {
64
65 ServerSocket listener;
66 try {
67 listener =
68 new ServerSocket(REGISTRATION_PORT);
69 }
70 catch (IOException e) {
71 // Need to signal main thread that
72 // no one is getting registered.
73 return;
74 }
75 try {
76
77 for (;;) {
78
79 Socket sock;
80 try {
81 sock = listener.accept();
82 }
83 catch (IOException e) {
84 System.out.println(e.toString());
85 e.printStackTrace();
86 continue;
87 }
88
89 System.out.println("Got a connection.");
90 registerClient(sock);
91 }
92 }
93 finally {
94 try {
95 listener.close();
96 }
97 catch (IOException e) {
98 }
99 }
100 }
101
102 private void registerClient(Socket sock) {
103
104 AddressAndPort anp;
105
106 // Grab the data from the client.
107 try {
108
109 ObjectInputStream ois =
110 new ObjectInputStream(
111 new BufferedInputStream(
112 sock.getInputStream()));
113
114 anp = (AddressAndPort) ois.readObject();
115 }
116 catch (ClassNotFoundException e) {
117 // Just abort registering this client
118 System.out.println(e.toString());
119 e.printStackTrace();
120 return;
121 }
122 catch (InvalidClassException e) {
123 // Just abort registering this client
124 System.out.println(e.toString());
125 e.printStackTrace();
126 return;
127 }
128 catch (StreamCorruptedException e) {
129 // Just abort registering this client
130 System.out.println(e.toString());
131 e.printStackTrace();
132 return;
133 }
134 catch (OptionalDataException e) {
135 // Just abort registering this client
136 System.out.println(e.toString());
137 e.printStackTrace();
138 return;
139 }
140 catch (IOException e) {
141 // Just abort registering this client
142 System.out.println(e.toString());
143 e.printStackTrace();
144 return;
145 }
146 finally {
147 try {
148 sock.close();
149 }
150 catch (IOException e) {
151 }
152 }
153
154 synchronized (ClockServer.this) {
155
156 int len = mailingList.size();
157
158 boolean found = false;
159 for (int i = 0; i canvasSize.height) {
82 outerCircleDiameter = canvasSize.height;
83 }
84 outerCircleDiameter -= 8;
85
86 int xOuterCircle = (canvasSize.width -
87 outerCircleDiameter) / 2;
88 int yOuterCircle = (canvasSize.height -
89 outerCircleDiameter) / 2;
90
91 // Paint with background color first
92 og.setColor(backgroundColor);
93 og.fillRect(0, 0, canvasSize.width, canvasSize.height);
94
95 // Draw lines around the edge of the canvas, to give
96 // it the appearance of a sunken panel.
97 og.setColor(shadowColor);
98 og.drawLine(0, 0, 0, canvasSize.height - 1);
99 og.drawLine(0, 0, canvasSize.width - 1, 0);
100
101 og.setColor(Color.white);
102 og.drawLine(0, canvasSize.height - 1,
103 canvasSize.width - 1, canvasSize.height - 1);
104 og.drawLine(canvasSize.width - 1, 0,
105 canvasSize.width - 1, canvasSize.height - 1);
106
107
108 // Draw arcs around the face of the clock
109 // to give it a raised appearance.
110 og.setColor(Color.white);
111 og.drawArc(xOuterCircle, yOuterCircle,
112 outerCircleDiameter, outerCircleDiameter, 45, 180);
113 og.setColor(shadowColor);
114 og.drawArc(xOuterCircle, yOuterCircle,
115 outerCircleDiameter, outerCircleDiameter, 45, -180);
116
117 // Radius of tick marks is 4 pixels less than radius
118 // of outer circle
119 int fullRadius = (outerCircleDiameter / 2) - 4;
120
121 // Radius of tip of the second hand
122 secondHandRadius = fullRadius + 1;
123
124 int minuteHandRadius = secondHandRadius;
125 int hourHandRadius = (fullRadius * 2) / 3;
126
127 xCircleCenter = xOuterCircle + (outerCircleDiameter / 2);
128 yCircleCenter = yOuterCircle + (outerCircleDiameter / 2);
129
130 // Calculate the absolute x and y positions for the
131 // tick marks that aren't at 12, 3, 6, or 9:00.
132 double shortSideDouble = ((double) fullRadius) *
133 Math.cos(Math.PI / 6.0);
134 double longSideDouble = ((double) fullRadius) *
135 Math.sin(Math.PI / 6.0);
136 int shortSide = (int) (shortSideDouble + 0.5);
137 int longSide = (int) (longSideDouble + 0.5);
138
139 // Put up 12 tick marks
140 // 12:00
141 drawTickMark(og, xCircleCenter, yCircleCenter - fullRadius);
142
143 // 1:00
144 drawTickMark(og, xCircleCenter + shortSide,
145 yCircleCenter - longSide);
146
147 // 2:00
148 drawTickMark(og, xCircleCenter + longSide,
149 yCircleCenter - shortSide);
150
151 // 3:00
152 drawTickMark(og, xCircleCenter + fullRadius, yCircleCenter);
153
154 // 4:00
155 drawTickMark(og, xCircleCenter + longSide,
156 yCircleCenter + shortSide);
157
158 // 5:00
159 drawTickMark(og, xCircleCenter + shortSide,
160 yCircleCenter + longSide);
161
162 // 6:00
163 drawTickMark(og, xCircleCenter, yCircleCenter + fullRadius);
164
165 // 7:00
166 drawTickMark(og, xCircleCenter - shortSide,
167 yCircleCenter + longSide);
168
169 // 8:00
170 drawTickMark(og, xCircleCenter - longSide,
171 yCircleCenter + shortSide);
172
173 // 9:00
174 drawTickMark(og, xCircleCenter - fullRadius, yCircleCenter);
175
176 // 10:00
177 drawTickMark(og, xCircleCenter - longSide,
178 yCircleCenter - shortSide);
179
180 // 11:00
181 drawTickMark(og, xCircleCenter - shortSide,
182 yCircleCenter - longSide);
183
184 Calendar cal = new GregorianCalendar();
185 cal.setTime(latestDate);
186
187 // Calculate the hour hand tip position
188 int hours = cal.get(Calendar.HOUR);
189 int minutes = cal.get(Calendar.MINUTE);
190 if (hours == 12) {
191 hours = 0;
192 }
193 int minPosOfHourHand = (hours * 5) + (minutes / 12);
194 Point hourHandTip = getHandTip(hourHandRadius,
195 minPosOfHourHand);
196
197 // Calculate the minute hand tip position
198 Point minuteHandTip = getHandTip(minuteHandRadius, minutes);
199
200 // Calculate the second hand tip position
201 int secs = cal.get(Calendar.SECOND);
202 Point secondHandTip = getHandTip(secondHandRadius, secs);
203
204 // Draw shadow of the 3 by 3 square in the center.
205 og.setColor(Color.black);
206 og.fillRect(xCircleCenter - 1, yCircleCenter - 1, 3, 3);
207
208 // Draw the hour hand
209 og.setColor(Color.blue);
210 og.drawLine(xCircleCenter, yCircleCenter,
211 hourHandTip.x, hourHandTip.y);
212
213 // Draw the minute hand
214 og.drawLine(xCircleCenter, yCircleCenter,
215 minuteHandTip.x, minuteHandTip.y);
216
217 // Draw a 2 by 2 square in the center on top
218 // of the shadow and hour and minute hands.
219 og.setColor(Color.red);
220 og.fillRect(xCircleCenter - 1, yCircleCenter - 1, 2, 2);
221
222 // Draw the second hand
223 og.drawLine(xCircleCenter, yCircleCenter,
224 secondHandTip.x, secondHandTip.y);
225
226 xSecondHandTip = secondHandTip.x;
227 ySecondHandTip = secondHandTip.y;
228
229 g.drawImage(offscreenImage, 0, 0, this);
230 }
231
232 private void drawTickMark(Graphics g, int x, int y) {
233
234 g.setColor(tickShadowColor);
235 g.fillRect(x, y, 2, 2);
236 g.setColor(Color.white);
237 g.fillRect(x, y, 1, 1);
238 }
239 }
--------------------------------------------------------------------------------
Multicast Protocol
TCP and UDP are unicast protocols: there is only one sender and one receiver.
Multicast packets are UDP packets that can take an arbitrary number of receivers.
Multicast uses "class D" IP addresses: 224.0.0.1 to 239.255.255.255.
Receivers "subscribe" to the multicast group (IP address).
Anyone can send to the group (not just subscribers). All subscribers are eligible to receive the packet.
// Join a Multicast group.
InetAddress group = InetAddress.getByName("225.6.7.8");
MulticastSocket ms = new MulticastSocket(7000);
ms.joinGroup(group);
// Send the group a datagram. (Don't need to be a
// member to send to the group.)
byte[] msg = {'H', 'o', 'w', 'd', 'y'};
DatagramPacket dp = new DatagramPacket(msg,
msg.length, group, 7000);
ms.send(dp);
// Get a datagram from the group.
byte[] buf = new byte[1000];
DatagramPacket recv = new DatagramPacket(buf,
buf.length);
ms.receive(recv);
// Leave the group.
ms.leaveGroup(group);
--------------------------------------------------------------------------------
URL and URLConnection
URL represents Uniform Resource Locator (a "pointer" to a resource on the network).
URLConnection lets you interact with the resource.
Create URLConnection by invoking openConnection() on a URL
Set up the URLConnection
Make the actual connection by invoking connect() on the URLConnection
Interact with the header fields and contents of the resource.
URLStreamHandlers (for protocols) and ContentHandlers (for MIME types) are loaded dynamically when needed.
--------------------------------------------------------------------------------
The Resource Grabber
1 // In file network/ex5/ResourceGrabber.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.Date;
5 import java.util.StringTokenizer;
6
7 public class ResourceGrabber {
8
9 public static void main(String[] args) {
10
11 if (args.length
Network Programming
Lecture Handout
--------------------------------------------------------------------------------
Seminars | Objects & Java | Design Workshop | Jini & Distrib | Objects & Patterns | Modules
Agenda
Introduce network programming, IP, and sockets
Give a client/server code example
Compare TCP and UDP
Introduce datagrams and give a code example
Touch on multicast protocol
Introduce URLs and give a code example
--------------------------------------------------------------------------------
Network Programming
Java's architecture is network-oriented.
The java.net library simplifies network programming.
You use Java I/O streams to communicate via sockets.
Java's built-in support for multi-threading simplifies creating server programs that must handle multiple client requests concurrently.
--------------------------------------------------------------------------------
IP and Sockets
IP (internet protocol) breaks communication into packets.
Packets routed and delivered separately
No delivery guarantee
Max packet size: 65535 (less a 20 byte header)
Sockets enable two machines to communicate via IP.
Other protocols layered on top of IP:
TCP (Transmission Control Protocol)
UDP (User Datagram Protocol)
--------------------------------------------------------------------------------
IP Addresses
IP requires that each machine have a unique IP address.
Represented by the InetAddress class of java.net.
IP Addresses are 32-bit numbers, often represented in these two forms:
host name (A DNS name such as artima.com)
quad form (205.73.4.217)
InetAddress.getByName(String) does DNS lookup (or reverse lookup) and returns an InetAddress object.
--------------------------------------------------------------------------------
Client/Server Computing
A socket connects a client and a server.
The server listens on a port for client requests.
Clients must specify the server's host IP Address and port number to make the request.
Once connected, the client/server distinction goes away from the sockets' perspective.
--------------------------------------------------------------------------------
Port Number
Port numbers are 16-bit unsigned integers (represented in Java by int's).
Each port represents a "service" offered by the host.
Ports 0 - 1024 are reserved for well-known services.
You should use parts above 1024 for your own servers.
Clients must specify both port and IP Address when making a connection request.
--------------------------------------------------------------------------------
Localhost
The reserved host name "localhost" allows you to test a network program without a network.
Server and clients can all exist on the same computer.
Three ways to get an InetAddress object for localhost:
InetAddress.getByName(null);
InetAddress.getByName("localhost");
InetAddress.getByName("127.0.0.1");
--------------------------------------------------------------------------------
The Summer Server Application
1 // In file network/ex1/SummerServer.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.StringTokenizer;
5
6 public class SummerServer {
7
8 public static final int PORT = 2000;
9
10 private static class InvalidLongException
11 extends Exception {
12
13 private String message;
14
15 InvalidLongException(String s) {
16 message = s;
17 }
18
19 public String getMessage() {
20 return message;
21 }
22 }
23
24 public static void main(String[] args)
25 throws IOException {
26
27 ServerSocket listener =
28 new ServerSocket(PORT);
29
30 try {
31
32 for (;;) {
33
34 Socket sock = listener.accept();
35
36 try {
37
38 serveClient(sock);
39 }
40 finally {
41 sock.close();
42 }
43 }
44 }
45 finally {
46 listener.close();
47 }
48 }
49
50 private static void serveClient(Socket sock)
51 throws IOException {
52
53 BufferedReader reader = new BufferedReader(
54 new InputStreamReader(
55 sock.getInputStream()));
56
57 BufferedWriter writer = new BufferedWriter(
58 new OutputStreamWriter(
59 sock.getOutputStream()));
60
61 for (;;) {
62
63 String s = reader.readLine();
64
65 if (s == null) {
66 break;
67 }
68
69 String outString;
70 try {
71 outString =
72 Long.toString(sumString(s));
73 }
74 catch(InvalidLongException e) {
75 outString = e.getMessage();
76 }
77 writer.write(outString);
78 writer.newLine();
79 writer.flush();
80 }
81 }
82
83 private static long sumString(String s)
84 throws InvalidLongException {
85
86 long sum = 0;
87
88 StringTokenizer st = new StringTokenizer(s);
89 String token;
90 while (st.hasMoreTokens()) {
91 token = st.nextToken();
92 try {
93 sum += Long.parseLong(token);
94 }
95 catch (NumberFormatException e) {
96 throw new InvalidLongException(
97 "Invalid number: " + token);
98 }
99 }
100
101 return sum;
102 }
103 }
104
1 // In file network/ex1/SummerClient.java
2 import java.net.*;
3 import java.io.*;
4
5 public class SummerClient {
6
7 public static void main(String[] args)
8 throws IOException {
9
10 InetAddress ia = InetAddress.getByName(null);
11
12 Socket sock = new Socket(ia, SummerServer.PORT);
13
14 try {
15
16 BufferedReader serverReader =
17 new BufferedReader(
18 new InputStreamReader(
19 sock.getInputStream()));
20
21 BufferedWriter serverWriter =
22 new BufferedWriter(
23 new OutputStreamWriter(
24 sock.getOutputStream()));
25
26 LineNumberReader stdinReader =
27 new LineNumberReader(
28 new BufferedReader(
29 new InputStreamReader(
30 System.in)));
31
32 for (;;) {
33
34 String userLine = stdinReader.readLine();
35
36 if (userLine == null ||
37 userLine.length() == 0) {
38
39 break;
40 }
41
42 serverWriter.write(userLine);
43 serverWriter.newLine();
44 serverWriter.flush();
45
46 String serverLine = serverReader.readLine();
47 System.out.println(serverLine);
48 }
49 }
50 finally {
51 sock.close();
52 }
53 }
54 }
55
--------------------------------------------------------------------------------
Handling Multiple Clients Concurrently
1 // In file network/ex2/SummerServer.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.StringTokenizer;
5
6 public class SummerServer {
7
8 public static final int PORT = 2000;
9
10 private static class InvalidLongException
11 extends Exception {
12
13 private String message;
14
15 InvalidLongException(String s) {
16 message = s;
17 }
18
19 public String getMessage() {
20 return message;
21 }
22 }
23
24 private static class SummerService
25 extends Thread {
26
27 private Socket sock;
28
29 public SummerService(Socket sock) {
30 this.sock = sock;
31 }
32
33 public void run() {
34
35 try {
36
37 BufferedReader reader =
38 new BufferedReader(
39 new InputStreamReader(
40 sock.getInputStream()));
41
42 BufferedWriter writer =
43 new BufferedWriter(
44 new OutputStreamWriter(
45 sock.getOutputStream()));
46
47 for (;;) {
48
49 String s = reader.readLine();
50
51 if (s == null) {
52 break;
53 }
54
55 String outString;
56 try {
57 outString =
58 Long.toString(sumString(s));
59 }
60 catch(InvalidLongException e) {
61 outString = e.getMessage();
62 }
63 writer.write(outString);
64 writer.newLine();
65 writer.flush();
66 }
67 }
68 catch (IOException e) {
69 }
70 finally {
71 try {
72 sock.close();
73 }
74 catch (IOException e) {
75 }
76 }
77 }
78 }
79
80 public static void main(String[] args)
81 throws IOException {
82
83 ServerSocket listener = new ServerSocket(PORT);
84
85 try {
86
87 for (;;) {
88
89 Socket sock = listener.accept();
90
91 SummerService ss =
92 new SummerService(sock);
93 ss.start();
94 }
95 }
96 finally {
97 listener.close();
98 }
99 }
100
101 private static long sumString(String s)
102 throws InvalidLongException {
103
104 long sum = 0;
105
106 StringTokenizer st = new StringTokenizer(s);
107 String token;
108 while (st.hasMoreTokens()) {
109 token = st.nextToken();
110 try {
111 sum += Long.parseLong(token);
112 }
113 catch (NumberFormatException e) {
114 throw new InvalidLongException(
115 "Invalid number: " + token);
116 }
117 }
118
119 return sum;
120 }
121 }
122
1 // In file network/ex2/SummerClient.java
2 import java.net.*;
3 import java.io.*;
4
5 public class SummerClient {
6
7 public static void main(String[] args)
8 throws IOException {
9
10 InetAddress ia = InetAddress.getByName(null);
11
12 Socket sock = new Socket(ia,
13 SummerServer.PORT);
14
15 try {
16
17 BufferedReader serverReader =
18 new BufferedReader(
19 new InputStreamReader(
20 sock.getInputStream()));
21
22 BufferedWriter serverWriter =
23 new BufferedWriter(
24 new OutputStreamWriter(
25 sock.getOutputStream()));
26
27 LineNumberReader stdinReader =
28 new LineNumberReader(
29 new BufferedReader(
30 new InputStreamReader(
31 System.in)));
32
33 for (;;) {
34
35 String userLine =
36 stdinReader.readLine();
37
38 if (userLine == null ||
39 userLine.length() == 0) {
40
41 break;
42 }
43
44 serverWriter.write(userLine);
45 serverWriter.newLine();
46 serverWriter.flush();
47
48 String serverLine =
49 serverReader.readLine();
50 System.out.println(serverLine);
51 }
52 }
53 finally {
54 sock.close();
55 }
56 }
57 }
58
--------------------------------------------------------------------------------
TCP versus UDP
The Summer Server examples use TCP.
TCP (Transmission Control Protocol):
"reliable" (the packets are guaranteed to get there)
packets arrive in the order they were sent
slower than UDP (reliability has overhead)
UDP (User Data Protocol):
"unreliable" (the packets aren't guaranteed to get there)
packets may arrive out of order
packets may arrive faster than they can be consumed
faster than TCP (because less overhead)
--------------------------------------------------------------------------------
Datagrams
Datagrams (UDP packets) are like letters:
You put the recipient's and your own return address (IP Address & Port Number) on the envelope.
You send it, but don't know if whether it will actually get there.
If you send a second letter tomorrow, that might get there first.
UDP is used for:
Clock tickers, game player position announcers, etc...
Streaming protocals such as RealAudio
Designing a faster reliable protocol than TCP
--------------------------------------------------------------------------------
Using Datagrams
Need a DatagramSocket on both client and server.
To send, place the data (up to 65535 bytes less 20-byte header) into a DatagramPacket.
On receiving end, get a DatagramPacket containing the data.
There is no "connection" as with TCP.
--------------------------------------------------------------------------------
The Clock Server
1 // In file network/ex3/ClockServer.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.StringTokenizer;
5 import java.util.Vector;
6 import java.util.Date;
7
8 public class ClockServer {
9
10 public static final int REGISTRATION_PORT = 2001;
11 private final static int ADDR_BYTE_SIZE = 4;
12
13 private Vector mailingList = new Vector();
14
15 public static class AddressAndPort
16 implements Serializable {
17
18 private InetAddress addr;
19 private int port;
20
21 public AddressAndPort(InetAddress addr, int port) {
22
23 this.addr = addr;
24 this.port = port;
25 }
26
27 public InetAddress getAddress() {
28 return addr;
29 }
30
31 public int getPort() {
32 return port;
33 }
34
35 public boolean equals(Object o) {
36
37 if (o == null) {
38 return false;
39 }
40
41 AddressAndPort anp;
42
43 try {
44 anp = (AddressAndPort) o;
45 }
46 catch (ClassCastException e) {
47 return false;
48 }
49
50 if (addr.equals(anp.addr) && port == anp.port) {
51 return true;
52 }
53 else {
54 return false;
55 }
56 }
57 }
58
59 private class RegistrationService extends Thread {
60
61 private Socket sock;
62
63 public void run() {
64
65 ServerSocket listener;
66 try {
67 listener =
68 new ServerSocket(REGISTRATION_PORT);
69 }
70 catch (IOException e) {
71 // Need to signal main thread that
72 // no one is getting registered.
73 return;
74 }
75 try {
76
77 for (;;) {
78
79 Socket sock;
80 try {
81 sock = listener.accept();
82 }
83 catch (IOException e) {
84 System.out.println(e.toString());
85 e.printStackTrace();
86 continue;
87 }
88
89 System.out.println("Got a connection.");
90 registerClient(sock);
91 }
92 }
93 finally {
94 try {
95 listener.close();
96 }
97 catch (IOException e) {
98 }
99 }
100 }
101
102 private void registerClient(Socket sock) {
103
104 AddressAndPort anp;
105
106 // Grab the data from the client.
107 try {
108
109 ObjectInputStream ois =
110 new ObjectInputStream(
111 new BufferedInputStream(
112 sock.getInputStream()));
113
114 anp = (AddressAndPort) ois.readObject();
115 }
116 catch (ClassNotFoundException e) {
117 // Just abort registering this client
118 System.out.println(e.toString());
119 e.printStackTrace();
120 return;
121 }
122 catch (InvalidClassException e) {
123 // Just abort registering this client
124 System.out.println(e.toString());
125 e.printStackTrace();
126 return;
127 }
128 catch (StreamCorruptedException e) {
129 // Just abort registering this client
130 System.out.println(e.toString());
131 e.printStackTrace();
132 return;
133 }
134 catch (OptionalDataException e) {
135 // Just abort registering this client
136 System.out.println(e.toString());
137 e.printStackTrace();
138 return;
139 }
140 catch (IOException e) {
141 // Just abort registering this client
142 System.out.println(e.toString());
143 e.printStackTrace();
144 return;
145 }
146 finally {
147 try {
148 sock.close();
149 }
150 catch (IOException e) {
151 }
152 }
153
154 synchronized (ClockServer.this) {
155
156 int len = mailingList.size();
157
158 boolean found = false;
159 for (int i = 0; i canvasSize.height) {
82 outerCircleDiameter = canvasSize.height;
83 }
84 outerCircleDiameter -= 8;
85
86 int xOuterCircle = (canvasSize.width -
87 outerCircleDiameter) / 2;
88 int yOuterCircle = (canvasSize.height -
89 outerCircleDiameter) / 2;
90
91 // Paint with background color first
92 og.setColor(backgroundColor);
93 og.fillRect(0, 0, canvasSize.width, canvasSize.height);
94
95 // Draw lines around the edge of the canvas, to give
96 // it the appearance of a sunken panel.
97 og.setColor(shadowColor);
98 og.drawLine(0, 0, 0, canvasSize.height - 1);
99 og.drawLine(0, 0, canvasSize.width - 1, 0);
100
101 og.setColor(Color.white);
102 og.drawLine(0, canvasSize.height - 1,
103 canvasSize.width - 1, canvasSize.height - 1);
104 og.drawLine(canvasSize.width - 1, 0,
105 canvasSize.width - 1, canvasSize.height - 1);
106
107
108 // Draw arcs around the face of the clock
109 // to give it a raised appearance.
110 og.setColor(Color.white);
111 og.drawArc(xOuterCircle, yOuterCircle,
112 outerCircleDiameter, outerCircleDiameter, 45, 180);
113 og.setColor(shadowColor);
114 og.drawArc(xOuterCircle, yOuterCircle,
115 outerCircleDiameter, outerCircleDiameter, 45, -180);
116
117 // Radius of tick marks is 4 pixels less than radius
118 // of outer circle
119 int fullRadius = (outerCircleDiameter / 2) - 4;
120
121 // Radius of tip of the second hand
122 secondHandRadius = fullRadius + 1;
123
124 int minuteHandRadius = secondHandRadius;
125 int hourHandRadius = (fullRadius * 2) / 3;
126
127 xCircleCenter = xOuterCircle + (outerCircleDiameter / 2);
128 yCircleCenter = yOuterCircle + (outerCircleDiameter / 2);
129
130 // Calculate the absolute x and y positions for the
131 // tick marks that aren't at 12, 3, 6, or 9:00.
132 double shortSideDouble = ((double) fullRadius) *
133 Math.cos(Math.PI / 6.0);
134 double longSideDouble = ((double) fullRadius) *
135 Math.sin(Math.PI / 6.0);
136 int shortSide = (int) (shortSideDouble + 0.5);
137 int longSide = (int) (longSideDouble + 0.5);
138
139 // Put up 12 tick marks
140 // 12:00
141 drawTickMark(og, xCircleCenter, yCircleCenter - fullRadius);
142
143 // 1:00
144 drawTickMark(og, xCircleCenter + shortSide,
145 yCircleCenter - longSide);
146
147 // 2:00
148 drawTickMark(og, xCircleCenter + longSide,
149 yCircleCenter - shortSide);
150
151 // 3:00
152 drawTickMark(og, xCircleCenter + fullRadius, yCircleCenter);
153
154 // 4:00
155 drawTickMark(og, xCircleCenter + longSide,
156 yCircleCenter + shortSide);
157
158 // 5:00
159 drawTickMark(og, xCircleCenter + shortSide,
160 yCircleCenter + longSide);
161
162 // 6:00
163 drawTickMark(og, xCircleCenter, yCircleCenter + fullRadius);
164
165 // 7:00
166 drawTickMark(og, xCircleCenter - shortSide,
167 yCircleCenter + longSide);
168
169 // 8:00
170 drawTickMark(og, xCircleCenter - longSide,
171 yCircleCenter + shortSide);
172
173 // 9:00
174 drawTickMark(og, xCircleCenter - fullRadius, yCircleCenter);
175
176 // 10:00
177 drawTickMark(og, xCircleCenter - longSide,
178 yCircleCenter - shortSide);
179
180 // 11:00
181 drawTickMark(og, xCircleCenter - shortSide,
182 yCircleCenter - longSide);
183
184 Calendar cal = new GregorianCalendar();
185 cal.setTime(latestDate);
186
187 // Calculate the hour hand tip position
188 int hours = cal.get(Calendar.HOUR);
189 int minutes = cal.get(Calendar.MINUTE);
190 if (hours == 12) {
191 hours = 0;
192 }
193 int minPosOfHourHand = (hours * 5) + (minutes / 12);
194 Point hourHandTip = getHandTip(hourHandRadius,
195 minPosOfHourHand);
196
197 // Calculate the minute hand tip position
198 Point minuteHandTip = getHandTip(minuteHandRadius, minutes);
199
200 // Calculate the second hand tip position
201 int secs = cal.get(Calendar.SECOND);
202 Point secondHandTip = getHandTip(secondHandRadius, secs);
203
204 // Draw shadow of the 3 by 3 square in the center.
205 og.setColor(Color.black);
206 og.fillRect(xCircleCenter - 1, yCircleCenter - 1, 3, 3);
207
208 // Draw the hour hand
209 og.setColor(Color.blue);
210 og.drawLine(xCircleCenter, yCircleCenter,
211 hourHandTip.x, hourHandTip.y);
212
213 // Draw the minute hand
214 og.drawLine(xCircleCenter, yCircleCenter,
215 minuteHandTip.x, minuteHandTip.y);
216
217 // Draw a 2 by 2 square in the center on top
218 // of the shadow and hour and minute hands.
219 og.setColor(Color.red);
220 og.fillRect(xCircleCenter - 1, yCircleCenter - 1, 2, 2);
221
222 // Draw the second hand
223 og.drawLine(xCircleCenter, yCircleCenter,
224 secondHandTip.x, secondHandTip.y);
225
226 xSecondHandTip = secondHandTip.x;
227 ySecondHandTip = secondHandTip.y;
228
229 g.drawImage(offscreenImage, 0, 0, this);
230 }
231
232 private void drawTickMark(Graphics g, int x, int y) {
233
234 g.setColor(tickShadowColor);
235 g.fillRect(x, y, 2, 2);
236 g.setColor(Color.white);
237 g.fillRect(x, y, 1, 1);
238 }
239 }
--------------------------------------------------------------------------------
Multicast Protocol
TCP and UDP are unicast protocols: there is only one sender and one receiver.
Multicast packets are UDP packets that can take an arbitrary number of receivers.
Multicast uses "class D" IP addresses: 224.0.0.1 to 239.255.255.255.
Receivers "subscribe" to the multicast group (IP address).
Anyone can send to the group (not just subscribers). All subscribers are eligible to receive the packet.
// Join a Multicast group.
InetAddress group = InetAddress.getByName("225.6.7.8");
MulticastSocket ms = new MulticastSocket(7000);
ms.joinGroup(group);
// Send the group a datagram. (Don't need to be a
// member to send to the group.)
byte[] msg = {'H', 'o', 'w', 'd', 'y'};
DatagramPacket dp = new DatagramPacket(msg,
msg.length, group, 7000);
ms.send(dp);
// Get a datagram from the group.
byte[] buf = new byte[1000];
DatagramPacket recv = new DatagramPacket(buf,
buf.length);
ms.receive(recv);
// Leave the group.
ms.leaveGroup(group);
--------------------------------------------------------------------------------
URL and URLConnection
URL represents Uniform Resource Locator (a "pointer" to a resource on the network).
URLConnection lets you interact with the resource.
Create URLConnection by invoking openConnection() on a URL
Set up the URLConnection
Make the actual connection by invoking connect() on the URLConnection
Interact with the header fields and contents of the resource.
URLStreamHandlers (for protocols) and ContentHandlers (for MIME types) are loaded dynamically when needed.
--------------------------------------------------------------------------------
The Resource Grabber
1 // In file network/ex5/ResourceGrabber.java
2 import java.net.*;
3 import java.io.*;
4 import java.util.Date;
5 import java.util.StringTokenizer;
6
7 public class ResourceGrabber {
8
9 public static void main(String[] args) {
10
11 if (args.length