互联网网站开发,网站推广分销系统,wordpress插件pdf,建网站用什么服务器好目录 TCP两个核心类
服务端
1.用ServerSocker类创建对象并且手动指定端口号
2.accept阻塞连接服务端与客户端
3.给客户端提供处理业务方法
4.处理业务
整体代码
客户端
1.创建Socket对象#xff0c;并连接服务端的ip与端口号
2.获取Socket流对象#xff0c;写入数据…目录 TCP两个核心类
服务端
1.用ServerSocker类创建对象并且手动指定端口号
2.accept阻塞连接服务端与客户端
3.给客户端提供处理业务方法
4.处理业务
整体代码
客户端
1.创建Socket对象并连接服务端的ip与端口号
2.获取Socket流对象写入数据阻塞等待服务端响应
整体代码
jconsole用来监控java线程 TCP两个核心类
ServerSocket 服务器使用socket
accept没有参数 返回值是一个Socket对象
功能是等待服务器和客户端建立连接建立成功后则会把这个连接获取到进程中。接下来就通过Scoket返回的对象来进行交互 Scoket服务器和客户端都使用socket
通过socket对象就可以进行发送接收数据
socket内部包含了输入流对象接收 输出流对象 发送 服务端
1.用ServerSocker类创建对象并且手动指定端口号 private ServerSocket serverSocketnull;public Test1(int port) throws IOException {serverSocketnew ServerSocket(port);
2.accept阻塞连接服务端与客户端 当我们用UDP那样连接客户端会出现一个问题 UDP是无连接的他发送数据时直接用地址端口号发送 而TCP是有连接的当我们用accept连接时ProcessConnect方法会一直被循环执行单个客户端而其他客户端要连接时无法执行到accept必须等待ProcessConnect方法执行结束所以会被阻塞。简单来说就是当有一个客户端连接时其他客户端必须等待连接的客户端断开连接才能连接还是一个个来连接。 所以ProcessConnect方法我们直接交给线程去执行这样其他客户端来连接时直接让线程去执行处理客户端业务。 所以我们可以用到多线程
既然用到了多线程就可以用出线程池效率会更高。
public void start() throws IOException {System.out.println(服务器启动);while (true){//阻塞等待服务器与客户端建立连接Socket socketserverSocket.accept();//若没线程 当一个客户端连接后 会一直在ProcessConnect内//其他客户端连接时 必须要等待ProcessConnect结束进入下一次循环才能执行到SocketsocketserverSocket.accept(); 才能连接下一个客户端
// // ProcessConnect(socket);//所以执行处理客户端请求我们让线程去干这样就不会在一个线程内阻塞
// Thread threadnew Thread(()-{
// try {
// ProcessConnect(socket);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// });
// thread.start();//线程池ExecutorService executorService Executors.newCachedThreadPool();executorService.submit(new Runnable() {Overridepublic void run() {try {ProcessConnect(socket);} catch (IOException e) {throw new RuntimeException(e);}}});}}
3.给客户端提供处理业务方法
我们可以直接获取Socket内的流对象直接写入读出即可
需要注意写入数据时因为时流对象接收要\n等待其他结束而我们输入数据时流对象是不会写入\n的所以我们可以在数据后自动添加\n 或者用println默认有个\n
public void ProcessConnect(Socket socket) throws IOException {//实际他们交流数据是一个为socket类型的文件System.out.printf([地址:%s:端口号%d]建立连接成功\n,socket.getInetAddress().toString(),socket.getPort());try (InputStream inputStream socket.getInputStream();//获取socket内部的input流OutputStream outputStream socket.getOutputStream())//获取socket内部的output流{Scanner scanner new Scanner(inputStream);PrintWriter printWriter new PrintWriter(outputStream);//长连接写法while (true) {if(!scanner.hasNext()){System.out.printf([地址:%s:端口号%d]断开连接,socket.getInetAddress().toString(),socket.getPort());}//从客户端接收数据String resqust scanner.next();System.out.println(服务器接收数据);//处理数据String response process(resqust);System.out.println(服务器处理数据);//因为这用流接收 我们按下换行是被scanner接收但并未添加到数据内 而服务器接收流收到的数据内//是没有换行符的 就会一直阻塞 所以我们要在数据后再加个\n//服务器发送数据//printWriter.write(response\n);//或者直接使用println自带\nprintWriter.println(response);System.out.println(服务器发送数据);//刷新缓冲区printWriter.flush();System.out.printf([地址:%s:端口号:%d]接收数据:%s 响应数据:%s,socket.getInetAddress().toString(),socket.getPort(),resqust,response);}}}
4.处理业务
这里是为了演示TCP连接所以只写个简单回传
public String process(String s){return s;}
整体代码
package TestTCP;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;//服务器
public class Test1 {private ServerSocket serverSocketnull;public Test1(int port) throws IOException {serverSocketnew ServerSocket(port);}public void start() throws IOException {System.out.println(服务器启动);while (true){//阻塞等待服务器与客户端建立连接Socket socketserverSocket.accept();//若没线程 当一个客户端连接后 会一直在ProcessConnect内//其他客户端连接时 必须要等待ProcessConnect结束进入下一次循环// 才能执行到SocketsocketserverSocket.accept(); 才能连接下一个客户端
// ProcessConnect(socket);//所以执行处理客户端请求我们让线程去干这样就不会在一个线程内阻塞
// Thread threadnew Thread(()-{
// try {
// ProcessConnect(socket);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// });
// thread.start();//线程池ExecutorService executorService Executors.newCachedThreadPool();executorService.submit(new Runnable() {Overridepublic void run() {try {ProcessConnect(socket);} catch (IOException e) {throw new RuntimeException(e);}}});}}//给当前客户端提供服务方法public void ProcessConnect(Socket socket) throws IOException {//实际他们交流数据是一个为socket类型的文件System.out.printf([地址:%s:端口号%d]建立连接成功\n,socket.getInetAddress().toString(),socket.getPort());try (InputStream inputStream socket.getInputStream();//获取socket内部的input流OutputStream outputStream socket.getOutputStream())//获取socket内部的output流{Scanner scanner new Scanner(inputStream);PrintWriter printWriter new PrintWriter(outputStream);//长连接写法while (true) {if(!scanner.hasNext()){System.out.printf([地址:%s:端口号%d]断开连接,socket.getInetAddress().toString(),socket.getPort());}//从客户端接收数据String resqust scanner.next();System.out.println(服务器接收数据);//处理数据String response process(resqust);System.out.println(服务器处理数据);//因为这用流接收 我们按下换行是被scanner接收但并未添加到数据内 而服务器接收流收到的数据内//是没有换行符的 就会一直阻塞 所以我们要在数据后再加个\n//服务器发送数据//printWriter.write(response\n);//或者直接使用println自带\nprintWriter.println(response);System.out.println(服务器发送数据);//刷新缓冲区printWriter.flush();System.out.printf([地址:%s:端口号:%d]接收数据:%s 响应数据:%s,socket.getInetAddress().toString(),socket.getPort(),resqust,response);}}}public String process(String s){return s;}public static void main(String[] args) throws IOException {Test1 t1new Test1(8080);t1.start();}
}客户端
1.创建Socket对象并连接服务端的ip与端口号 private Socket socketnull;public Test2() throws IOException {socketnew Socket(127.0.0.1,8080);
2.获取Socket流对象写入数据阻塞等待服务端响应 public void start() throws IOException {try(InputStream inputStreamsocket.getInputStream();OutputStream outputStreamsocket.getOutputStream()){while (true){Scanner scannernew Scanner(inputStream);PrintWriter printWriternew PrintWriter(outputStream);Scanner scanner1new Scanner(System.in);System.out.println(输入数据);String requstscanner1.next();//因为这用流接收 我们按下换行是被scanner接收但并未添加到数据内 而服务器接收流收到的数据内//是没有换行符的 就会一直阻塞 所以我们要在数据后再加个\n//printWriter.write(requst\n);//或者直接使用println自带\nprintWriter.println(requst);//刷新缓冲区printWriter.flush();String responsescanner.next();System.out.println(response);}}finally {socket.close();}}
整体代码
package TestTCP;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;//客户端
public class Test2 {private Socket socketnull;public Test2() throws IOException {socketnew Socket(127.0.0.1,8080);}public void start() throws IOException {try(InputStream inputStreamsocket.getInputStream();OutputStream outputStreamsocket.getOutputStream()){while (true){Scanner scannernew Scanner(inputStream);PrintWriter printWriternew PrintWriter(outputStream);Scanner scanner1new Scanner(System.in);System.out.println(输入数据);String requstscanner1.next();//因为这用流接收 我们按下换行是被scanner接收但并未添加到数据内 而服务器接收流收到的数据内//是没有换行符的 就会一直阻塞 所以我们要在数据后再加个\n//printWriter.write(requst\n);//或者直接使用println自带\nprintWriter.println(requst);//刷新缓冲区printWriter.flush();String responsescanner.next();System.out.println(response);}}finally {socket.close();}}public static void main(String[] args) throws IOException {Test2 t2new Test2();t2.start();}
}jconsole用来监控java线程
jconsole在路径 jdk/bin/jconsole.exe
例 我们需要看util最后一局可以看出线程是在next阻塞着。