Java中的Socket
在java.net包下有两个类:Socket和ServerSocket。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。服务端往Socket的OutputStream
里面写东西,客户端就可以通过Socket的InputStream
读取对应的内容。Socket与Socket之间是双向连通的,所以客户端也可以往对应的SocketOutputStream
里面写东西,然后服务端对应的Socket的InputStream
就可以读出对应的内容。
需要用到的两个构造方法:
Socket(InetAddress address,int port)
//创建一个流套接字并将其连接到指定 IP 地址的指定端口号
Socket(String host,int port)
//创建一个流套接字并将其连接到指定主机上的指定端口号
其中address、host和port分别是双向连接中另一方的IP地址、主机名和端 口号。注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,ftp服务的端口号为23, 所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。
服务器:ServerSocket(port)
客户机:Socket(ip, port) //服务器的ip 和 服务器的端口
以下是一个简单的服务器和客户端通信的demo,不支持多客户端的链接
服务器代码:
package com.socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static int port = 3007;
public static void main(String[] args) {
try {
ServerSocket ss = new ServerSocket(port);
System.out.println("开始在"+ port +"端口启动服务器...");
String clientMsg, serverMsg="";
Scanner sc = new Scanner(System.in);
while (!serverMsg.equals("bye")) {
Socket socket = ss.accept();
System.out.println("链接已建立");
//InputStream input = s.getInputStream();
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//OutputStream output = s.getOutputStream();
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
InputReader tIntput = new InputReader(input, "client");
tIntput.start();
while (!serverMsg.equals("bye")) {
// System.out.println("client says : " + clientMsg);
//
serverMsg = sc.nextLine();
//后面必须要加 \r 换行符
output.write(serverMsg + "\r");
output.flush();
}
tIntput.isRun = false;
socket.close();
sc.close();
System.out.println("server关闭连接");
}
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码:
package com.socket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
try {
Socket s = new Socket("localhost", 3007);
//InputStream input = s.getInputStream();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
//OutputStream output = s.getOutputStream();
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
String serverMsg;
InputReader tIntput = new InputReader(input, "server");
tIntput.start();
Scanner sc = new Scanner(System.in);
String clientMsg = sc.nextLine();
while(true){
//必须要在后面加一个 \r 换行符
output.write(clientMsg +"\r");
output.flush();
// serverMsg = input.readLine();
// System.out.println("server says : "+ serverMsg);
if(clientMsg.equals("bye")) break;
clientMsg = sc.nextLine();
}
tIntput.isRun = false;
sc.close();
s.close();
System.out.println("client关闭连接");
} catch (IOException e) {
e.printStackTrace();
}
}
}
InputReader.class:
package com.socket;
import java.io.BufferedReader;
import java.io.IOException;
public class InputReader extends Thread {
BufferedReader br;
String type;
boolean isRun = true;
public void setRun(boolean b){
this.isRun = b;
}
InputReader(BufferedReader br, String type){
this.br = br;
this.type = type;
}
public void run() {
try {
while(isRun){
String msg = br.readLine();
System.out.println(this.type +" : "+ msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
需要特别注意的是
output.write(clientMsg +"\r");
这个"\r"换行符不能少,否则readLine()
方法一直没有遇到换行,会一直等待读取。。。
我们在命令行中分别运行Server和Client:
先是服务器
客户端
连接成功
测试互相发送消息: