socket之事例
1.使用ServerSocket和Socket实现服务器端和客户端的 Socket通信:
2.面试题目总结;
1.面试题目1总结:
面试题目一:编写一个网络应用程序,有客户端与服务器端,客户端向服务器发送一个字符串,服务器收到该字符串后将其打印到命令行上,然后向客户端返回该字符串的长度,最后,客户端输出服务器端返回的该字符串的长度
//客户端代码
public class Client {
public static void main(String[] args) {
Socket socket = new Socket("127.0.0.1", 65000);
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
os.write(new String("hello world").getBytes());
int ch = 0;
byte[] buff = new byte[1024];
ch = is.read(buff);
String content = new String(buff, 0, ch);
System.out.println(content);
is.close();
os.close();
socket.close();}
}
// 服务端代码
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(65000);
while (true) {
Socket socket = serverSocket.accept();
new ServerThread(socket).start();}
}
class ServerThread extends Thread {
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
int ch = 0;
byte[] buff = new byte[1024];
ch = is.read(buff);
String content = new String(buff, 0, ch);
System.out.println(content);
os.write(String.valueOf(content.length()).getBytes());
is.close();
os.close();
socket.close();
}}}
}
面试题二:用UDP通信方式完成上述问题?
public class UDPClient { // 客户端代码
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(); // 客户端发数据报给服务端
byte[] buf = "Hello World".getBytes(); // 要发送给服务端的数据
InetAddress address = InetAddress.getByName("127.0.0.1"); // 将IP地址封装成InetAddress对象
// 将要发送给服务端数据封装成DatagramPacket对象 需要填写上ip地址与端口号
DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 65001);
socket.send(packet); // 发送数据给服务端
byte[] data = new byte[100]; // 客户端接受服务端发送过来的数据报
DatagramPacket receivedPacket = new DatagramPacket(data, data.length); // 创建DtagramPacket对象用来存储服务端发送过来的数据
socket.receive(receivedPacket); // 将接受到的数据存储到DatagramPacket对象中
String content = new String(receivedPacket.getData(), 0, receivedPacket.getLength());
System.out.println(content);}
}
public class UDPServer { // 服务端代码
public static void main(String[] args) {
// 服务端接受客户端发送的数据报
DatagramSocket socket = new DatagramSocket(65001);
byte[] buff = new byte[100]; //存储从客户端接受到的内容
DatagramPacket pocket = new DatagramPacket(buff, buff.length);
socket.receive(pocket); //接受客户端发送过来的内容,并将内容封装进DatagramPacket中
byte[] data = pocket.getData(); //从DatagramPacket对象中获取到真正存储的数据
String content = new String(data, 0, pocket.getLength()); //将数据从二进制转换成字符串形式
System.out.println(content);
byte[] sendedContent = String.valueOf(content.length()).getBytes(); // 将要发送给客户端的数据转换成二进制
// 服务端给客户端发送数据报,从DatagramPacket对象中获取到数据的来源地址与端口号
DatagramPacket packetToClient = new DatagramPacket(sendedContent, sendedContent.length, pocket.getAddress(), pocket.getPort());
socket.send(packetToClient); //发送数据给客户端 }
}
案例14. 使用ServerSocket和Socket实现服务器端和客户端的 Socket通信:
总结:
1) 建立Socket连接
2) 获得输入/输出流
3)读/写数据
4) 关闭输入/输出流
5) 关闭Socket
1. 编写网络应用程序,有客户端与服务器端,客户端向服务器端发送一个字符串,服务器收到该字符串后将其打印到命令行上,
然后向客户端返回该字符串的长度,最后,客户端输出服务器端返回的该字符串的长度。
public class ClientTest{
public static void main(String[] args) {
Socket socket = new Socket("localhost",9999);
OutputStream os = socket.getOutputStream();
String content = "This comes from client";
os.write(content.getBytes());
byte[] b = new byte[100];
InputStream is = socket.getInputStream();
int length = is.read(b);
String str = new String(b,0,length);
System.out.println("string's length:" + str);
is.close();
os.close();
socket.close(); }
}
public class SocketServerTest{
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(9999);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
byte[] buffer = new byte[100];
int length = is.read(buffer);
String content = new String(buffer,0,length);
System.out.println("read from client:" + content);
String str = String.valueOf(content.length());
OutputStream os = socket.getOutputStream();
os.write(str.getBytes());
is.close();
os.close();
socket.close();}
}
案例13:用socket编写一个服务端与客户端的聊天程序
//客户端代码
public class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 65000);
new MyThread(socket).start(); //开启一个线程用于处理已连接上的socket
}
//服务器端代码: 监听端口,每成功连接一个客户机就开启一个线程进行读写处理
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(65000);
while (true) {
Socket socket = ss.accept();
new MyThread(socket).start(); //开启一个线程用于处理已连接上的socket}}
}
//开启两个线程分别用来处理socket中的输入输出流
class MyThread extends Thread {
private Socket socket;
public MyThread(Socket socket) {
this.socket = socket;
}
public void run() {
try {
//开启两个线程分别来处理服务端的读写
new OutputThread(socket.getOutputStream()).start();
new InputThread(socket.getInputStream()).start();
} catch (IOException e) {}}
}
//处理socket的输出流
class OutputThread extends Thread {
private OutputStream os;
public OutputThread(OutputStream os) {
this.os = os;
}
public void run() {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
try {
while ((line = br.readLine()) != null) {
os.write((line).getBytes());
os.flush();
}
} }
}
//处理socket的输入流
class InputThread extends Thread {
private InputStream is;
public InputThread(InputStream is) {
this.is = is;
}
public void run() {
int ch = 0;
byte[] buff = new byte[1024];
try {
while ((ch = is.read(buff)) != -1) {
String content = new String(buff, 0, ch);
System.out.println(content);}
} }}
server 服务器端,处理数据连接,并转发消息
* 聊天室服务端
public class Server {
* 运行在服务端的ServerSocket主要负责:
* 1. 向系统申请服务端口客户端就是通过这个端口与之建立连接的
* 2. 监听申请的服务端口,当一个客户端通过该端口尝试建立连接时,ServerSocket会在
* 服务端创建一个Socket与客户端建立连接。
private ServerSocket server;
* 保存所有客户端输出流的集合
private Map<String,PrintWriter> allOut;
* 用来初始化服务端
public Server() throws IOException{
* 初始化的同时申请服务端口
server = new ServerSocket(8088);
allOut = new HashMap<String,PrintWriter>();
}
* 入口方法
public static void main(String[] args) {
try {
Server server = new Server();
server.start();
}catch(Exception e) {
e.printStackTrace();
System.out.println("服务端启动失败");
}
}
* 将给定的输出流添加到共享集合
private synchronized void addOut(String nickName,PrintWriter out) {
allOut.put(nickName, out);
}
* 将给定的输出流从共享集合中删除
private synchronized void removeOut(String nickName) {
allOut.remove(nickName);
}
* 将给定的消息发送给所有客户端
private void sendMessage(String message) {
Set<Map.Entry<String, PrintWriter>> entryset = allOut.entrySet();
for(Map.Entry<String, PrintWriter> e: entryset) {
e.getValue().println(message);
}
}
* 将给定消息发送给特定上线用户
private void sendOneMessage(String whoName,String message) {
String keyName = message.substring(1,message.indexOf(":"));
PrintWriter out = allOut.get(keyName);
System.out.println("out is "+out+keyName);