对于Java Socket编程而言,有两个概念,一个是ServerSocket,一个是Socket。服务端和客户端之间通过Socket建立连接,之后它们就可以进行通信了。首先ServerSocket将在服务端监听某个端口,当发现客户端有Socket来试图连接它时,它会accept该Socket的连接请求,同时在服务端建立一个对应的Socket与之进行通信。这样就有两个Socket了,客户端和服务端各一个。
服务端代码
Java代码 public class Server {
-
-
public static void main(String args[]) throws IOException {
-
//为了简单起见,所有的异常信息都往外抛
-
int port = 8899;
-
//定义一个ServerSocket监听在端口8899上
-
ServerSocket server = new ServerSocket(port);
-
//server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的
-
Socket socket = server.accept();
-
//跟客户端建立好连接之后,我们就可以获取socket的InputStream,并从中读取客户端发过来的信息了。
-
Reader reader = new InputStreamReader(socket.getInputStream());
-
char chars[] = new char[64];
-
int len;
-
StringBuilder sb = new StringBuilder();
-
while ((len=reader.read(chars)) != -1) {
-
sb.append(new String(chars, 0, len));
-
}
-
System.out.println("from client: " + sb);
-
reader.close();
-
socket.close();
-
server.close();
-
}
-
-
}
public class Server { public static void main(String args[]) throws IOException { //为了简单起见,所有的异常信息都往外抛 int port = 8899; //定义一个ServerSocket监听在端口8899上 ServerSocket server = new ServerSocket(port); //server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的 Socket socket = server.accept(); //跟客户端建立好连接之后,我们就可以获取socket的InputStream,并从中读取客户端发过来的信息了。 Reader reader = new InputStreamReader(socket.getInputStream()); char chars[] = new char[64]; int len; StringBuilder sb = new StringBuilder(); while ((len=reader.read(chars)) != -1) { sb.append(new String(chars, 0, len)); } System.out.println("from client: " + sb); reader.close(); socket.close(); server.close(); } }
服务端从Socket的InputStream中读取数据的操作也是阻塞式的,如果从输入流中没有读取到数据程序会一直在那里不动,直到客户端往Socket的输出流中写入了数据,或关闭了Socket的输出流。当然,对于客户端的Socket也是同样如此。在操作完以后,整个程序结束前记得关闭对应的资源,即关闭对应的IO流和Socket。
客户端代码
Java代码
-
public class Client {
-
-
public static void main(String args[]) throws Exception {
-
//为了简单起见,所有的异常都直接往外抛
-
String host = "127.0.0.1"; //要连接的服务端IP地址
-
int port = 8899; //要连接的服务端对应的监听端口
-
//与服务端建立连接
-
Socket client = new Socket(host, port);
-
//建立连接后就可以往服务端写数据了
-
Writer writer = new OutputStreamWriter(client.getOutputStream());
-
writer.write("Hello Server.");
-
writer.flush();//写完后要记得flush
-
writer.close();
-
client.close();
-
}
-
-
}
public class Client { public static void main(String args[]) throws Exception { //为了简单起见,所有的异常都直接往外抛 String host = "127.0.0.1"; //要连接的服务端IP地址 int port = 8899; //要连接的服务端对应的监听端口 //与服务端建立连接 Socket client = new Socket(host, port); //建立连接后就可以往服务端写数据了 Writer writer = new OutputStreamWriter(client.getOutputStream()); writer.write("Hello Server."); writer.flush();//写完后要记得flush writer.close(); client.close(); } }
对于客户端往Socket的输出流里面写数据传递给服务端要注意一点,如果写操作之后程序不是对应着输出流的关闭,而是进行其他阻塞式的操作(比如从输入流里面读数据),记住要flush一下,只有这样服务端才能收到客户端发送的数据,否则可能会引起两边无限的互相等待。在稍后讲到客户端和服务端同时读和写的时候会说到这个问题。