初次接触到socket网络编程,也参考了网络上众前辈的文章。尝试自己也写了一下,记录下过程吧:
服务端:(接收客户端消息并把它们打印出来)
public class SocketServer {
private List<Socket> socketList = new ArrayList<Socket>();
public static void main(String[] args) {
SimServer ss = new SimServer();
try {
ss.service();
} catch (IOException e) {
e.printStackTrace();
}
}
public void service() throws IOException {
ServerSocket server = new ServerSocket(7001);
SimServer ss = new SimServer();
while (true) {
Socket socket = server.accept();
socketList.add(socket);
ServerThread st = new ServerThread(socket, socketList);
st.start();
}
}
class ServerThread extends Thread {
private Socket client;
private List<Socket> socketList;
public ServerThread(Socket client, List<Socket> socketList) {
this.client = client;
this.socketList = socketList;
}
@Override
public void run() {
BufferedReader in = null;
PrintWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
while (true) {
String msg = in.readLine();
System.out.println(InetAddress.getLocalHost().getHostAddress() + " 客户端请求:" +msg);
// System.out.print("服务端请输入:");
// String input = new BufferedReader(new InputStreamReader(System.in)).readLine();
System.out.println();
for(int i=0; i<socketList.size(); i++) {
// out = new PrintWriter(client.getOutputStream());
out = new PrintWriter(socketList.get(i).getOutputStream());
out.println("服务端返回:" + msg);
out.println();
out.flush();
// out.println("Server handle: " + Arrays.toString(msg.getBytes()));
// out.write("Server handle: " + Arrays.toString(msg.getBytes()));
// String lineSeprator = (String) java.security.AccessController.doPrivileged(
// new sun.security.action.GetPropertyAction("line.separator"));
// out.write(lineSeprator);
// if (msg.equals("bye")) {
// break;
// }
}
}
} catch(IOException ex) {
ex.printStackTrace();
} finally {
try {
in.close();
} catch (Exception e) {}
try {
out.close();
} catch (Exception e) {}
try {
// client.close();
} catch (Exception e) {}
}
}
}
}
客户端:(发送消息并接收消息,这个应该是异步的,所以必须创建两个线程)
public class SocketClient {
class Send extends Thread {
private Socket socket;
public Send(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
PrintWriter out = null;
BufferedReader input = null;
try {
out = new PrintWriter(socket.getOutputStream());
input = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.print(InetAddress.getLocalHost().getHostAddress()+" 客户端请输入:");
String msg = input.readLine();
out.println(msg);
out.flush();
}
// socket.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(input != null)
input.close();
if(out != null)
out.close();
// if(socket != null)
// socket.close();
} catch (Exception e) {}
}
}
}
class Recv extends Thread {
private Socket socket;
public Recv(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
System.out.println();
String msg = reader.readLine();
System.out.println(msg);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(reader != null)
reader.close();
// if(socket != null)
// socket.close();
} catch (Exception e) {}
}
}
}
public static void main(String[] args) {
SimClient sc = new SimClient();
try {
Socket s = new Socket("localhost", 7001);
sc.new Recv(s).start();
sc.new Send(s).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
(可在另一台机器上有一个一模一样的客户端,只不过ip地址要改为服务器所在的机器的ip)
-----------------------------------
在此过程中,发现了几点:
1)服务端用的是ServerSocket,每当有一个客户端连接上服务端,就会触发serverSocket.accept()产生一个socket用于和客户端交互;
2)PrintWriter.write(String msg)无法把消息发出去,而PrintWriter.println(String msg)则可以,但println(String msg)相当于(要同时write lineSeprator):
out.write("Server handle: " + Arrays.toString(msg.getBytes()));
String lineSeprator = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
out.write(lineSeprator);
3)服务端线程必须把socketList传进来,它才能知道有几个客户端连着它。