什么是Socket和什么是Socket编程
Socket通常称为套接字,应用程序通常通过套接字向网络发出请求。Java语言中的Socket编程常用到Socket和ServerSocket这两个类,Socket用于端对端的通信,而ServerSocket用于服务端对象的创建,它们都位于Java.net包中
基于TCP的Socket编程
•从图可见,Socket 编程是由服务器端和客户端两部分组成的,并且二者是相互交错通信的,因此在编写代码时就不能像以前那样先把一个类写完毕之后再编写第二个类,而应该是交错式的同步编写。例如,先在服务端类中创建服务对象及 accept() 方法,然后编写客户端类,在客户端类中创建 Socket 对象,之后再切换到服务端类编写 OutputStream 对象。换句话说,在 Socket 编程中,服务端和客户端互为依赖,在编写代码时二者都需要借助对方的已有代码。
利用多线程处理多客户端请求
如图,客户端在请求连接客户端时,每个客户端会创建一个Socket,所以服务端在相应连接时,也会相应创建多个Socket,所以我们需要在相应连接时,每个客户端创建一个线程。明白思路后。
这里利用发生对象流,所以创建了一个student类
import java.io.Serializable;
//将要传递的对象序列化
public class Student implements Serializable {
private int sid;
private String name;
private int age;
public Student() {
}
public Student(int sid, String name, int age) {
this.sid = sid;
this.name = name;
this.age = age;
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
服务器线程代码
package NetWork.MuThread;
import NetWork.Base.Student;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class ServerThread extends Thread{
Socket socket;
public ServerThread(Socket socket){
this.socket=socket;
}
@Override
public void run() {
InputStream in=null;
ObjectInputStream ois=null;
Student student=null;
OutputStream out=null;
try {
in = socket.getInputStream();
ois =new ObjectInputStream(in);
student = (Student)ois.readObject();
System.out.println(student);
socket.getInputStream();
out =socket.getOutputStream();
out.write("ok".getBytes(StandardCharsets.UTF_8));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(out !=null) out.close();
if(ois !=null) ois.close();
if(in !=null) in.close();
if(socket !=null) socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
服务端代码
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ThreadMyServer {
public static void main(String[] args) {
ServerSocket serverSocket =null;
try {
serverSocket=new ServerSocket(8841);
while (true){
// 每接收到一个客户机的申请连接,就创建一个线程
Socket socket=serverSocket.accept();
ServerThread serverThread =new ServerThread(socket);
serverThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码一个示例
import java.io.*;
import java.net.Socket;
public class MyClient1 {
public static void main(String[] args) {
Socket socket =null;
ObjectOutputStream oos=null;
OutputStream out =null;
BufferedReader reader=null;
InputStream in=null;
try {
socket =new Socket("127.0.1",8841);
Student student =new Student(1,"zs",23);
out= socket.getOutputStream();
oos = new ObjectOutputStream(out);
oos.writeObject(student);
socket.shutdownOutput();
in = socket.getInputStream();
reader= new BufferedReader(new InputStreamReader(in));
String info;
while ((info=reader.readLine())!=null){
System.out.println("I am Cilent,接收到的消息"+info);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (reader != null) reader.close();
if (in != null) in.close();
if (oos != null) oos.close();
if (out != null) out.close();
if (socket != null) socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
能同时对多个客户端进行监听
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7pcdoztm-1668592079582)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20221116174731922.png)]