java面试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();
}
}
}
class MyThread extends Thread {
private Socket socket;
public MyThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
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();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//客户端代码
public class Client {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1", 65000);
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
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();
}
}
面试题目二:请用UDP通信方式完成上述问题,并说说UDP与TCP的区别
答案:具体代码见如下所示
//服务端代码
public class UDPServer {
public static void main(String[] args) throws Exception {
// 服务端接受客户端发送的数据报
DatagramSocket socket = new DatagramSocket(65001); //监听的端口号
byte[] buff = new byte[100]; //存储从客户端接受到的内容
DatagramPacket pocket = new DatagramPacket(buff, buff.length);
//接受客户端发送过来的内容,并将内容封装进DatagramPacket对象中
socket.receive(pocket);
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); //发送数据给客户端
}
}
//客户端的代码
public class UDPClient {
public static void main(String[] args) throws Exception {
// 客户端发数据报给服务端
DatagramSocket socket = new DatagramSocket();
// 要发送给服务端的数据
byte[] buf = "Hello World".getBytes();
// 将IP地址封装成InetAddress对象
InetAddress address = InetAddress.getByName("127.0.0.1");
// 将要发送给服务端的数据封装成DatagramPacket对象 需要填写上ip地址与端口号
DatagramPacket packet = new DatagramPacket(buf, buf.length, address,
65001);
// 发送数据给服务端
socket.send(packet);
// 客户端接受服务端发送过来的数据报
byte[] data = new byte[100];
// 创建DtagramPacket对象用来存储服务端发送过来的数据
DatagramPacket receivedPacket = new DatagramPacket(data, data.length);
// 将接受到的数据存储到DatagramPacket对象中
socket.receive(receivedPacket);
// 将服务器端发送过来的数据取出来并打印到控制台
String content = new String(receivedPacket.getData(), 0,
receivedPacket.getLength());
System.out.println(content);
}
}
UDP与TCP的区别是:UDP是用户数据报协议是无连接的,不可靠的,数据的到达时间,到达顺序,数据是否能够到达及数据到达的完整性都是无法保证的,类似于寄信,适用于视频会议等对速度要求高但对数据完整性要求不严格的场景,而TCP是传输控制协议,数据的传输建立在连接之上,是可靠的,TELNET、FTP、HTTP都是建立在TCP之上的,因为有连接所以在JAVA中用输入输出流来传输数据。
用UDP编程使用到类DatagramSocket、DatagramPacket
用TCP编程使用到类ServerSocket、Socket
面试题目三:用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;
}
@Override
public void run() {
try {
//开启两个线程分别来处理服务端的读写
new OutputThread(socket.getOutputStream()).start();
new InputThread(socket.getInputStream()).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//处理socket的输出流
class OutputThread extends Thread {
private OutputStream os;
public OutputThread(OutputStream os) {
this.os = os;
}
@Override
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();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//处理socket的输入流
class InputThread extends Thread {
private InputStream is;
public InputThread(InputStream is) {
this.is = is;
}
@Override
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);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//客户端代码
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
}
}
面试题目四:Collections和Collection的区别?
答案:Collections是集合辅助类,里面提供了一系列方法来方便我们操纵集合,而Collection是List与Set的父接口
面试题目五:HashTable和HashMap区别
答案:HashTable是同步的、在单线程环境下效率低,它的键与值都不能为空。HashMap是不同步的、在单线程环境下效率高,它的键与值都可为空。
面试题目六:如下两个程序能否编译通过?并说明为什么
//代码-1
short s = 1;
s = s + 1;
//代码-2
short s = 1;
s += 1;
答案:代码-1不能够编译通过,因为执行s + 1
操作的时候,低类型会自动往高类型转,所以执行完后的结果是int类型,然后int类型是无法直接赋值给short类型的,必须要进行向下类型转换才可。而代码-2可以编译通过,因为使用了+=
的运算符,该运算符隐藏着强制类型转换的操作,相等于s = (short) (s + 1);