netthreadjdbc

本文深入解析TCP/IP协议栈各层功能,包括应用层、传输层、网络层和链路层的关键协议,并探讨Unix环境下Socket编程实践。通过Java代码示例,展示服务器与客户端的通信过程,以及如何利用多线程提升网络程序的并发能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说说TCP/IP?

应用层   http  ftp  ssh  dns  smtp  pop  telnet  …. 

传输层  tcp  udp 

网络层  ip  icmp

链路层  arp  rarp

C 在 unix  实现协议相关的代码

计算机世界网络编程统称  socket编程

常用网络相关命令:

ping  route    nslookup   arp    netstat    ipconfig/ifconfig/ip

 

import java.net.ServerSocket;

class TcpServer {

   public static void main(String[] args) {

      try {

         ServerSocket server = new ServerSocket(5555);

         System.in.read();

      } catch (Exception e) {

            System.out.println(e.getMessage());

      } finally {     

      }

   }

}

 

运行程序后,打开命令行window:netstat   -ano| find  “:5555”

linux:  netstat   -anp| grep “:5555”

  

TcpServer.java

import java.net.ServerSocket;

 

class TcpServer {

   public static void main(String[] args) {

 

      try {

         ServerSocket server = new ServerSocket(5555);

         server.accept();

         System.in.read();

      } catch (Exception e) {

            System.out.println(e.getMessage());

      } finally {

     

      }

 

   }

}

YkClient.java

import java.net.ServerSocket;

import java.net.Socket;

 

class YkClient {

   public static void main(String[] args) {

     

      try {

         new Socket("localhost", 5555);

         System.in.read();

        

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

     

   }

}

先运行服务器,再运行客户端,使用netstat查看信息

YkClient.java

 

import java.net.ServerSocket;

import java.net.Socket;

 

class YkClient {

   public static void main(String[] args) {

     

      try {

       Socket socket=    new Socket("localhost", 5555);

       socket.getOutputStream().write("i'myangkang".getBytes());

       System.in.read();      

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

     

   }

}

 

TcpServer.java

 

import java.net.ServerSocket;

import java.net.Socket;

 

class TcpServer {

   public static void main(String[] args) {

 

      try {

         ServerSocket server = new ServerSocket(5555);

         Socket socket=server.accept();

         byte b[]=new byte[100];

         int len= socket.getInputStream().read(b);

         System.out.println(new String(b, 0, len));

         System.in.read();

      } catch (Exception e) {

            System.out.println(e.getMessage());

      } finally {

     

      }

 

   }

}

 

 

运行服务器,如果出现bind问题,说明占用端口的进程还在运行,杀掉占用端口的进程再运行即可

YkClient.java

 

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

 

class YkClient {

   public static void main(String[] args) {   

      try {

       Socket socket=    new Socket("localhost", 5555);

       OutputStream  out= socket.getOutputStream();

       String str = null;

       byte bMsg[] = new byte[200];

         while (true) {

              System.out.print("ykclient>");

            int len = System.in.read(bMsg);

            if (len == 2)

                continue;

            str = new String(bMsg, 0, len - 2);

            if (str.equals("quit") || str.equals("exit")) {

                System.exit(0);

            }

            out.write(bMsg, 0, len-2);

       }

     

           

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

     

   }

}

TcpServer.java

 

import java.io.InputStream;

import java.net.ServerSocket;

import java.net.Socket;

 

class TcpServer {

   public static void main(String[] args) {

 

      try {

         ServerSocket server = new ServerSocket(5555);

         Socket socket = server.accept();

         InputStream in = socket.getInputStream();

         byte b[] = new byte[100];

         while (true) {

            int len = in.read(b);

            System.out.println(new String(b, 0, len));

         }

      } catch (Exception e) {

         System.out.println(e.getMessage());

      } finally {

 

      }

 

   }

}

 

运行效果

2018年12月3日星期一

 

软件、程序、进程、线程

 

打开任务管理器,查看mysql服务器进程的线程数量

 

每个人用mysql客户端和我们自己的写的客户端连接mysql数据库

再看看线程的数量

 

不停使用mysql客户端连接服务器,直到看到线程数量增加

 

 

线程可以看着是程序里面的小程序,是可以独立运行的代码段,线程这个功能是CPU和OS提供的,不是语言提供的

 

 

并发   和   并行概念?

 

class ThreadA extends Thread {

   @Override

   public void run() {

      // for 输出1 3 5 7 9

      for (int i = 1; i <= 9; i = i + 2) {

         System.out.println(i);

         try {

            sleep(1);

         } catch (InterruptedException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

         }

      }

   }

}

 

class ThreadB implements Runnable {

   @Override

   public void run() {

      // do while输出2 4 6 8 10

      int i = 2;

      do {

         System.out.println(i);

         i = i + 2;

         try {

            Thread.sleep(1);

         } catch (InterruptedException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

         }

      } while (i <= 10);

 

   }

}

 

class TestT {

   public static void main(String[] args) {

      Thread t1 = new ThreadA();

      Thread t2 = new Thread(new ThreadB());

      t1.start();

      t2.start();

 

      new Thread(new Runnable() {

 

         @Override

         public void run() {

            for (int i = 1; i <= 4; i++) {

                System.out.println(i);

                try {

                   Thread.sleep(1);

                } catch (InterruptedException e) {

                   // TODO Auto-generated catch block

                   e.printStackTrace();

                }

            }

 

         }

      }).start();

 

   }

}

 

将程序多运行几次,看输出结果

 

调整网络程序、增加线程

 

调整服务器代码

TcpServer.java

import java.net.ServerSocket;

import java.net.Socket;

 

class TcpServer {

   public static void main(String[] args) {

 

      try {

         ServerSocket server = new ServerSocket(5555);

         while (true) {

            Socket socket = server.accept();

            new CommThread(socket).start();

         }

      } catch (Exception e) {

         System.out.println(e.getMessage());

      } finally {

 

      }

 

   }

}

创建线程处理和每个客户端的通信

import java.io.InputStream;

import java.net.Socket;

 

class CommThread extends Thread {

 

   private Socket socket;

 

   public CommThread() {

 

   }

 

   public CommThread(Socket socket) {

      this.socket = socket;

   }

 

   @Override

   public void run() {

      // 写和每一个客户端通信的代码,怎么区分不同客户端(通过Socket

      try {

         System.out.println(getName() + "-" + socket);

         InputStream in = socket.getInputStream();

         byte b[] = new byte[200];

         while (true) {

            int len = in.read(b);

            System.out.println(new String(b, 0, len));

         }

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

 

   }

}

客户端代码不变

YkClient.java

 

import java.io.OutputStream;

import java.net.ServerSocket;

import java.net.Socket;

 

class YkClient {

   public static void main(String[] args) {   

      try {

       Socket socket=    new Socket("localhost", 5555);

       OutputStream  out= socket.getOutputStream();

       String str = null;

       byte bMsg[] = new byte[200];

         while (true) {

              System.out.print("ykclient>");

            int len = System.in.read(bMsg);

            if (len == 2)

                continue;

            str = new String(bMsg, 0, len - 2);

            if (str.equals("quit") || str.equals("exit")) {

                System.exit(0);

            }

            out.write(bMsg, 0, len-2);

       }

     

           

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

     

   }

}

布置一个任务,创建一张表

msginfo(id  自动增长字段, msg  varchar(200),  msgdate  date);

自动增长字段:Oracle 使用sequence   ;mysql使用auto_increment。

 

使用jdbc将聊天消息保存到数据库

public void run() {

      // 写和每一个客户端通信的代码,怎么区分不同客户端(通过Socket

      try {

         System.out.println(getName() + "-" + socket);

         InputStream in = socket.getInputStream();

         byte b[] = new byte[200];

         while (true) {

            int len = in.read(b);

            String msg=new String(b, 0, len);

            //   使用jdbc将消息保存到数据库          

            String sql="insert into msginfo(msg,msgdate) values('"+msg+"',sysdate/now())";

            System.out.println(sql);//输出sql检查sql是否正确   

            System.out.println(msg);

         }

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

 

   }

提醒:先运行程序,客户端发个消息,服务器端能看到正确的sql语句后再将jdbc操作代码搬过来

 

写一个执行insert/delete/update的

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

 

class Db {

   private Connection getConn() {

      Connection conn = null;

      try {

         // 把和数据库建立连接的代码复制过来

         Class.forName("driver");

         conn = DriverManager.getConnection("url", "user", "pass");

 

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

      return conn;

 

   }

 

   public boolean exeUpdate(String sql) throws SQLException {

      Connection conn = getConn();

      try {

         Statement st = conn.createStatement();

         int cnt = st.executeUpdate(sql);

         return cnt > 0;

      } catch (Exception e) {

         System.err.println(e.getMessage());

         return false;

      } finally {

         if (conn != null) {

            conn.close();

         }

      }

 

   }

 

}

 

public void run() {

      // 写和每一个客户端通信的代码,怎么区分不同客户端(通过Socket

      try {

         System.out.println(getName() + "-" + socket);

         InputStream in = socket.getInputStream();

         byte b[] = new byte[200];

         while (true) {

            int len = in.read(b);

            String msg=new String(b, 0, len);

            //   使用jdbc将消息保存到数据库          

            String sql="insert into msginfo(msg,msgdate) values('"+msg+"',sysdate/now())";

             new Db().exeUpdate(sql);

            System.out.println(msg);

         }

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

 

   }

 

 

如何将每个客户端发的消息发送到其他客户端?

 

只要记住有哪些客户端就行了

 

调整服务器

class TcpServer {

  public static void main(String[] args) {

 

     try {

       ServerSocket server = new ServerSocket(5555);

       List<Socket> lst=new ArrayList<Socket>();

      

       while (true) {

         Socket socket = server.accept();

         lst.add(socket);

         new CommThread(socket, lst).start();

       }

     } catch (Exception e) {

       System.out.println(e.getMessage());

     } finally {

 

     }

 

  }

}

调整线程

class CommThread extends Thread {

 

   private Socket socket;

   private List<Socket> lst;

 

   public CommThread() {

 

   }

 

   public CommThread(Socket socket, List<Socket> lst) {

      super();

      this.socket = socket;

      this.lst = lst;

   }

 

   private void pushMsg(byte b[], int len) {

      for (Socket skt : lst) {

         if (skt == socket) {

            continue;

         }

         try {

            OutputStream out = skt.getOutputStream();

            out.write(b, 0, len);

         } catch (Exception e) {

            System.err.println(e.getMessage());

         }

 

      }

 

   }

 

   @Override

   public void run() {

      // 写和每一个客户端通信的代码,怎么区分不同客户端(通过Socket

      try {

 

         InputStream in = socket.getInputStream();

         byte b[] = new byte[200];

         while (true) {

            int len = in.read(b);

            String msg = new String(b, 0, len);

            // 使用jdbc将消息保存到数据库

            String sql = "insert into msginfo(msg,msgdate) values('" + msg + "',sysdate/now())";

            new Db().exeUpdate(sql);

 

            // 只要将收到的消息向其他客户端发送

            pushMsg(b, len);

 

         }

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

 

   }

}

调整客户端

class YkClient {

   public static void main(String[] args) {   

      try {

       Socket socket=    new Socket("localhost", 5555);

        // 创建一个线程对象专门接收服务器发来的信息

     

       

       OutputStream  out= socket.getOutputStream();

       String str = null;

       byte bMsg[] = new byte[200];

         while (true) {

              System.out.print("ykclient>");

            int len = System.in.read(bMsg);

            if (len == 2)

                continue;

            str = new String(bMsg, 0, len - 2);

            if (str.equals("quit") || str.equals("exit")) {

                System.exit(0);

            }

            out.write(bMsg, 0, len-2);

       }

     

           

      } catch (Exception e) {

         System.err.println(e.getMessage());

      }

     

   }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值