Java Sockets编程
TCP提供了一个可靠的,点对点的客户端-服务器应用通道,想要在TCP上进行传输,客户端程序与服务器程序需要建立彼此的连接。客户端和服务器都是对与连接绑定的socket进行读和写来传输数据。
What is a Socket?
客户端请求数据的过程:
服务器listen到之后,accept这个请求并与client进行连接
- 定义:socket是一个互联网上双向连接中的一个端点(An endpoint)。
java.net
包提供了两个class:Socket、ServerSocket
,分别实现了客户端与服务器端的连接。
端点(An endpoint)是IP地址与端口号的结合。每个TCP连接都有他的两个端点唯一确定
另外,如果你想连接Web,URL class
和相关类(URLConnection,URLEncoder
)可能比sokect更加合适,实际上,URLs 是对Web的一种相对高层的连接,sockets则作为底层实现
Reading from and writing to a Socket
package demo;
import java.io.*;
import java.net.*;
public class EchoClient {
public static void main(String args[]) throws IOException {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try{
echoSocket = new Socket("taranis", 7);
//write to the socket
out = new PrintWriter(echoSocket.getOutputStream(), true);
//read the socket
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
}catch (UnknownHostException e){
System.err.println("Don't know about host");
System.exit(1);
}catch (IOException e){
System.err.println("couldn't get I/O for the connection to taranis");
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while((userInput = stdIn.readLine())!= null) {
out.println(userInput);
System.out.println("echo : " + in.readLine());
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}
在应用中,应遵守如下顺序:
- Open a socket.
- Open an input stream and output stream to the socket.
- Read from and write to the stream 4. according to the server's protocol.
- Close the streams.
- Close the socket.
Writing the Server Side of a Socket
The Knock Knock Server
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
}
catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
accept方法一直到客户端启动并向服务器发出请求为止一直在等待。但注意,此方法不支持多个客户端同时访问
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
这段代码:
- 得到socket的inputstream&outputstream,在stream上打开reader和writer
- 通过向socket写操作来初始化传输
- 与客户端进行读和写
readLine方法一直等到客户端对socket的outputstream写入(对服务器socket的inputstream的写入)才运行
The Knock Knock Protocol
所有的服务器/客户端对必须有他们用于对话某种协议,否则,来回传送的数据就变得没有意义了。协议取决于你要完成什么任务
Supporting Multiple Clients
多用户请求实际上可以从一个port进入,客户端的请求在服务器端排成队列。所以服务器必须按顺序解决他们。通过多线程来解决问题
如下:
while (true) {
accept a connection;
create a thread to deal with the client;
}