关闭

网络编程 TCP

547人阅读 评论(0) 收藏 举报

TCP网络程序的工作原理。TCP客户端程序与TCP服务器端程序交互的过程:
①服务器程序创建一个ServerSocket,然后调用accept方法等待客户来连接。
②客户端程序创建一个Socket并请求与服务器建立连接。
③服务器接收客户的连接请求,并创建一个新的Socket与该客户建立专线连接。
④建立了连接的两个Socket在一个单独的线程(由服务器程序创建)上的对话。
⑤服务器开始等待新的连接请求,当新的连接请求到达时重复②到⑤的过程。


简单的TCP服务器程序:
TCP服务器程序必须先启动运行,TCP客户程序才能连接上TCP服务器。
①使用windows提供的telnet程序测试TCP服务器程序。
我的电脑IP为:192.168.1.103 端口号:8001
telnet 192.168.1.103 8001
②使用BufferedReader包装类,从网络输入流中一次读取一行文本。
InputStream ips=new InputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(ips));
③如何打开telnet程序的本地回显功能。
windows xp 系统为:
set localecho

程序代码:
package TCPSocket;
import java.net.*;
import java.io.*;
public class TcpServer {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  try{
   ServerSocket ss=new ServerSocket(8001);
   Socket s=ss.accept();
   //构建输入输出流对象用于向客户端输出数据和读取客户端的数


   InputStream ips=s.getInputStream();
   OutputStream ops=s.getOutputStream();
   ops.write("abc--china".getBytes());
      //构建字节数组对象读取数据
   BufferedReader br=new BufferedReader(new

InputStreamReader(ips));
   System.out.println(br.readLine());
   /*该方法一读取到数据就向客户端发送数据 程序停止关闭连接
    * byte [] buf=new byte[1024];
   int len=ips.read(buf);
      //将读取到的字节数组数据转化为字符数据
   System.out.println(new String(buf,0,len));*/
   
   //ips.close();
   br.close();
   ops.close();
   s.close();
   ss.close();
  }catch(Exception e){
   e.printStackTrace();
  }
  }

 }
该程序只能完成服务器与一个客户端的数据交换,与实际应用有差别,需要改进。

改进后的程序:
ReverseSocket类:
package TCPSocket;
import java.net.*;
public class ReverseServer {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  try{
   ServerSocket ss=new ServerSocket(8001);
   boolean bRuning=true;
   while(bRuning){
    Socket s=ss.accept();
    new Thread(new servicer(s)).start();
    
   }
   ss.close();
  }catch(Exception e){
   e.printStackTrace();
  }
 }

 }
servicer类:
package TCPSocket;
import java.net.*;
import java.io.*;
public class servicer implements Runnable {
     private Socket s=null;
     public servicer(Socket s){
     
      this.s=s;
     }
 @Override
 public void run() {
  // TODO Auto-generated method stub
       try{
        InputStream ips=s.getInputStream();
     OutputStream ops=s.getOutputStream();
     BufferedReader br=new BufferedReader(
       new InputStreamReader(ips));
     //为了方便打印一行内容到客户端 定义一个PrintWriter包装ops对象
     //设置为true很关键 将会刷新缓冲区保证读取的字符能输出到客户端屏幕上
     PrintWriter pw=new PrintWriter(ops,true);
     /*调用println方法将字符串写入到底层输出流,并在字符串后增加换行符
               在windows下产生:"/r/n";在Linux下产生:"/n"
              与PrintStream中println()方法的区别: 无论在哪种系统下产生的都是"/n"换行符     、
       */
   
           while(true){
            String StrLine=br.readLine();
            if(StrLine.equalsIgnoreCase("quit")){
             break;
            }
            System.out.println(StrLine+":"+StrLine.length());
            //调用StringBuffer的reverse()方法反向排列其传入的字符串
         String strEcho =  new StringBuffer(StrLine).reverse().toString();
            pw.println(StrLine+"-->"+strEcho);
  }
           br.close();
           pw.close();
           s.close();
          }catch(Exception e){
         e.printStackTrace();
        }
    
 }

}
/*说明:在本程序中如果在客户端输入有backspace键那么在程序反向排列的过程中也会有backspace
 * 例如:abc(backspace)d-->d(backspace)cba 在客户端看到的是abd 反向排序后返回的是cba
 * */

 

TCP服务器程序模块的编写要点总结:
①TCP服务器程序要想接收多个客户端的连接,需要循环调用ServerSocket.accept方法
②服务器程序与每个客户端连接的会话过程不能相互影响,需要在独立的线程中运行。
③一个线程对象与一个服务器端Socket对象相关联,共同来完成与一个客户端的会话。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:53325次
    • 积分:869
    • 等级:
    • 排名:千里之外
    • 原创:28篇
    • 转载:2篇
    • 译文:0篇
    • 评论:21条
    文章分类
    最新评论