110分:JAVA中Socket如何发送和接收字节数组?
问题点数:110、回复次数:23Top
1 楼grantdyg(撤剑)回复于 2001-09-24 21:30:31 得分 10
先用getOutputStream(),再由PrintWriter来操作不行吗?Top
2 楼cmpp()回复于 2001-09-24 21:32:16 得分 0
楼上的朋友给个代码先!Top
3 楼hegum(大概)回复于 2001-09-25 08:22:33 得分 40
我的省略了的部分参考:
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();}//捕或异常
}
}//服务器程序结束
Top
4 楼robber(海盗)回复于 2001-09-25 09:16:27 得分 10
readLine()固然很好,可是别人要求的是收发byte[] .而且,readLine()在接受二进制数据的时候有问题!
因此,可以使用
InputStream.read(byte[])
和
OutputStream.write(byte[])
注意:
read方法需要检测返回值。至于为什么?请查考JDK API文档。
Top
5 楼skyyoung(路人甲)回复于 2001-09-25 09:17:02 得分 25
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 < len; ++i) {
160
161 Object o = mailingList.elementAt(i);
162
163 if (anp.equals(o)) {
164 found = true;
165 System.out.println(
166 "Already registered: (" +
167 anp.getAddress().getHostAddress() +
168 ", " + anp.getPort() + ")");
169 break;
170 }
171 }
172
173 if (!found) {
174 mailingList.addElement(anp);
175 System.out.println("Registering: (" +
176 anp.getAddress().getHostAddress() + ", "
177 + anp.getPort() + ")");
178 }
179 }
180 }
181 }
182
183 private class TickerService extends Thread {
184
185 public void run() {
186
187 DatagramSocket sock;
188
189 try {
190 sock = new DatagramSocket();
191 }
192 catch (SocketException e) {
193 System.out.println(e.toString());
194 e.printStackTrace();
195 return;
196 }
197
198 for (;;) {
199
200 // Create the Datagram
201 Date date = new Date();
202
203 ByteArrayOutputStream baos =
204 new ByteArrayOutputStream();
205 ObjectOutputStream oos;
206 try {
207 oos = new ObjectOutputStream(baos);
208 oos.writeObject(date);
209 oos.close();
210 }
211 catch (IOException e) {
212 return;
213 }
214
215 byte[] data = baos.toByteArray();
216
217 Vector ml;
218 synchronized (this) {
219 ml = (Vector) mailingList.clone();
220 }
221
222 int len = ml.size();
223
224 for (int i = 0; i < len; ++i) {
225
226 AddressAndPort anp =
227 (AddressAndPort) ml.elementAt(i);
228
229 InetAddress ia = anp.getAddress();
230 int port = anp.getPort();
231
232 DatagramPacket dp =
233 new DatagramPacket(data,
234 data.length, ia, port);
235
236 try {
237 sock.send(dp);
238 }
239 catch (IOException e) {
240 }
241 System.out.println("Sending to port: " +
242 port);
243 }
244
245 try {
246 Thread.sleep(1000);
247 }
248 catch (InterruptedException e) {
249 }
250 }
251 }
252 }
253
254 private void start() {
255 RegistrationService rs = new RegistrationService();
256 rs.start();
257 TickerService ts = new TickerService();
258 ts.start();
259 }
260
261 public static void main(String[] args)
262 throws IOException {
263
264 ClockServer cs = new ClockServer();
265 cs.start();
266 }
267 }
268
--------------------------------------------------------------------------------
The Clock Applet
1 // In file network/ex3/ClockApplet.java
2 import java.applet.*;
3 import java.net.*;
4 import java.io.*;
5 import java.awt.*;
6 import java.util.Date;
7
8 public class ClockApplet extends Applet {
9
10 private int myPort = 4000;
11 private Runner runner;
12 private CoolClockCanvas clock =
13 new CoolClockCanvas();
14
15 private class Runner extends Thread {
16
17 private boolean stopRequested;
18
19 void requestStop() {
20 stopRequested = true;
21 }
22
23 public void run() {
24
25 for (;;) {
26
27 if (stopRequested) {
28 return;
29 }
30
31 try {
32 InetAddress ia =
33 InetAddress.getByName(null);
34
35 ClockServer.AddressAndPort myANP =
36 new ClockServer.AddressAndPort(
37 ia, myPort);
38
39 Socket sock = new Socket(ia,
40 ClockServer.REGISTRATION_PORT);
41
42 try {
43
44 ObjectOutputStream oos =
45 new ObjectOutputStream(
46 new BufferedOutputStream(
47 sock.getOutputStream()));
48
49 try {
50 oos.writeObject(myANP);
51 }
52 finally {
53 oos.close();
54 }
55 }
56 finally {
57 sock.close();
58 }
59
60 DatagramSocket dgsock;
61
62 try {
63 dgsock = new DatagramSocket(myPort);
64 }
65 catch (SocketException e) {
66 System.out.println(e.toString());
67 e.printStackTrace();
68 return;
69 }
70
71 for (;;) {
72
73 int packetSize = 1000;
74 byte[] buf = new byte[packetSize];
75
76 DatagramPacket dp =
77 new DatagramPacket(
78 buf, packetSize);
79
80 dgsock.receive(dp);
81 System.out.println("Datagram received");
82
83 byte[] data = dp.getData();
84
85 ByteArrayInputStream bais =
86 new ByteArrayInputStream(data);
87
88 ObjectInputStream ois;
89 Date date;
90 try {
91 ois = new ObjectInputStream(bais);
92 date = (Date) ois.readObject();
93 ois.close();
94 }
95 catch (IOException e) {
96 System.out.println(e.toString());
97 e.printStackTrace();
98 continue;
99 }
100 catch (ClassNotFoundException e) {
101 System.out.println(e.toString());
102 e.printStackTrace();
103 continue;
104 }
105
106 clock.setTime(date);
107 }
108 }
109 catch (IOException e) {
110 System.out.println(e.toString());
111 e.printStackTrace();
112 return;
113 }
114 }
115 }
116 }
117
118 public void init() {
119
120 String portStr = getParameter("port");
121 if (portStr != null) {
122 try {
123 myPort = Integer.parseInt(portStr);
124 }
125 catch (NumberFormatException e) {
126 // Use default port number
127 }
128 }
129
130 setLayout(new BorderLayout());
131 add("Center", clock);
132 }
133
134 public synchronized void start() {
135
136 if (runner == null) {
137
138 runner = new Runner();
139 runner.start();
140 }
141 }
142
143 public synchronized void stop() {
144
145 if (runner != null) {
146
147 runner.requestStop();
148 runner = null;
149 }
150 }
151 }
152
1 // In file network/ex3/CoolClockCanvas.java
2 import java.awt.*;
3 import java.awt.event.*;
4 import java.util.*;
5
6 class CoolClockCanvas extends Canvas {

