您的位置:首页 > 编程语言

Socket初步编程——简单实现群聊

2017-04-06 15:59 225 查看
初次接触到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传进来,它才能知道有几个客户端连着它。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: