`
lzkyo
  • 浏览: 457925 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

TCP/IP协议(Socket)做服务器,HTTP协议做客户端

阅读更多

前几天在本区看到一个贴子,有人问,在Socket做服务器,在手机上用Http访问,如何实现。这个贴子,有十来个人回复了,可惜回复的都是:Socket使用TCP/IP协议,客户端用HTTP协议,不同协议不可能实现通讯。再可惜,那个贴子结了,要不然,我就可以回复了!在这里拿出来说一下,让大家不要再误会了(TCP/IP与HTTP不可通讯)  
  因为目前很多手机仍不支持MIDP2.0,只支持MIDP1.0,而Socket技术只在MIDP2.0才提供支持,所以,一般的Java   ME程序的如果要实现C/S结构,都会选用Tomcat等服务器、sevlet或JavaBean等Java   EE架构实现。不过,考虑到响应速度与性能的问题,Tomcat等Java   EE架构可能满足不了业务要求,这样,我们就要用到下面将要说的自已写服务器的技术了。        
  一般的C/S结构程序,一般程序员都会写,不过,这里一般程序员刚接触Socket写服务器,Http写客户端都会头大——不可能吧,Socket用TCP/IP协议,客户端用Http协议,不同协议间,怎么可能通讯呢!        
  本文要说的就是这个问题了。        
  大家一定都知道,网络系统一共分7层,在这七层中,Http协议要高于TCP/IP协议(因为在互联网中,计算机是通过IP定位的,也就是用TCP/IP协议了),对网络操作系统有了解的人,一定不会忘记,我们用Http访问www的时候,用的是域名,而域名,最终还是要通过DNS转换成IP地址的。这就对了——HTTP协议基于TCP/IP协议!而Socket正是基于TCP/IP协议,这样一来,它们就有了共同之外了!有了以上的认识,理论方面就没问题了。        
  我们再讨论一下实现:        
  服务器:        
  和一般的C/S结构一样,用Socket(java中用ServerSocket)监听。监听、读写消息的方面与一般的C/S服务器一模一样。不同的是,考虑到客户端只支持http协议,所以,读客户端消息的时候,读到的将是http头+消息,那么,我们便要用程序分析并去掉http头,只用消息。发消息的时候正好相反,在发送的消息前面,自己加上http头(其实就是一个包含一定内容的字符串),这样再发出去,客户端就可以收到并读取了。    
  客户端:        
  用Http连接,在java中,用的是HttpConnection.open("http://"+IP+":"+Port)访问服务器,这样,就可以向ServerSocket请求连接了。        
  在open之后,再向HttpConnection对象的输出流写入消息,然后刷新流再关闭HttpConnection就可以了,客户端因为本来用的就是http协议,所以不用自行加http头,底层会处理的;服务器在Accept()之后,就可以从Socket的输入流读到消息了。当然,如果要读服务器的消息的话,可以在HttpConnection关闭前读它的输入流(读的时候,如果还没有收到服务器消息,会阻塞当前线程的,直到读到为止,不怕读不到)。客户端读到的消息,是不包括http头的,所以,也就不用我们自行处理了。    
  要注意的是,HttpConnetion.open后,只能用一次,刷新后,它就无效了,得重新调用open方法再次建立连接。(服务器最好使用线程建立Socket与客户端连接,连接一次一个线程。)  

 

服务器示例代码:(共三个类)   
  //HttpServer.java   
  package   testnetserver;   
    
  public   class   HttpServer{   
  public   HttpServer()   {   
  }   
  public   static   void   main(String[]   aregs){   
  HttpServerSocket   hss=new   HttpServerSocket();   
  hss.start();   
  }   
  }   
    
    
    
    
    
    
  //HttpServerSocket.java   
  package   testnetserver;   
    
  import   java.net.ServerSocket;   
  import   java.io.*;   
    
  public   class   HttpServerSocket   extends   Thread{   
  ServerSocket   ss=null;   
  private   static   final   int   port=2222;   
  public   HttpServerSocket()   {   
  }   
  public   void   run(){   
  try   {   
  ss   =   new   ServerSocket(port);   
  }   
  catch   (IOException   ex)   {   
  System.out.println("ServerSocket   can   not   listen");   
  System.out.println("Error   on   ServerSocket   bind   port");   
  ex.printStackTrace();   
  ss=null;   
  return;   
  }   
  //循环监听   
  while(true){   
  HttpSocket   hs=null;   
  try   {   
  hs=new   HttpSocket();   
  hs.s=ss.accept();   
  System.out.println("have   a   client   connect");   
  hs.start();   
  }   
  catch   (IOException   ex1)   {   
  System.out.println("Error   on   accept");   
  }   
  }   
  }   
  }   
    
    
    
    
    
    
  //HttpSocket.java   
  package   testnetserver;   
    
  import   java.net.Socket;   
  import   java.io.*;   
    
  public   class   HttpSocket   
  extends   Thread   {   
  public   Socket   s   =   null;   
  String   msg   =   "";   
  public   HttpSocket()   {   
  }   
    
  public   void   run()   {   
  BufferedReader   is   =   null;   
  PrintWriter   os   =   null;   
  try   {   
  //由Socket对象得到输入流,并构造相应的BufferedReader对象   
  is   =   new   BufferedReader(new   InputStreamReader(s.getInputStream()));   
  //由Socket对象得到输出流,并构造PrintWriter对象   
  os   =   new   PrintWriter(s.getOutputStream());   
  }   
  catch   (IOException   ex)   {   
  System.out.println("Error   on   get   Buffere");   
  }   
    
  String   temp   =   "";   
  try   {   
  temp   =   is.readLine();   
  while   (temp   !=   null)   {   
  msg   +=   temp;   
  if   (temp.length()   >   4   &&   
  temp.substring(temp.length()   -   4).equals("/End"))   {   
  temp   =   is.readLine();   //虚读   
  temp   =   null;   
  break;   
  }   
  msg   +=   "\r\n";   
  temp   =   is.readLine();   
  }   
  getMsg();   
  //立刻回发消息   
  msg   =   "Begin/"   +   msg   +   "/End";   
  os.write("HTTP/1.1   200   OK\r\n");   
  os.write("Content-Type:   text;   charset=utf\r\n");   
  os.write(   ("Content-Length:   "   +   msg.length()   +   "\r\n"));   
  os.write("\r\n");   
  os.write(msg);   
  os.flush();   
  msg   =   "";   
  }   
  catch   (IOException   ex1)   {   
  System.out.println("Error   on   read   or   write   Buffered");   
  ex1.printStackTrace();   
  }   
  try   {   
  sleep(100);   
  }   
  catch   (InterruptedException   ex2)   {   
  System.out.println("Error   on   HttpSocket   sleep");   
  }   
  }   
    
  //去掉协议头,取出纯消息   
  private   void   getMsg()   {   
  int   begin   =   msg.indexOf("Begin/");   
  int   end   =   msg.indexOf("/End");   
  if   (begin   >=   0   &&   end   >   0   &&   msg.length()>"Begin/".length())   {   
  msg   =   msg.substring(begin   +   "Begin/".length(),   end);   
  System.out.println(msg);   
  }   
  else   {   
  msg   =   "";   
  }   
  }   
  }   

 

 

客户端示例代码(主要部份):   
  public   void   run()   {   
  HttpConnection   conn   =   null;   
  DataInputStream   dis   =   null;   
  DataOutputStream   dos   =   null;   
  int   begin   =   0,   end   =   0;   
  byte   temp[]   =   new   byte[10000];   
  int   len   =   0;   
  try   {   
  conn   =   (HttpConnection)   Connector.open("http://"   +   IP   +   ":"   +   
  port);   
                          //写输出流(向服务器发送信息)   
  dos   =   conn.openDataOutputStream();   
  msg   =   "Begin/"   +   msg+"/End";   
  //dos.writeUTF(msg);   
  dos.write(msg.getBytes());   
  dos.flush();   
  dos.close();   
  if   (!isTestConnectTime)   {   
  dataLenght   =   msg.length();   
  }   
  backTime   =   0;   
  //读输入流(读服务器消息)   
  dis   =   conn.openDataInputStream();   
  len   =   dis.read(temp);   
  if   (len   >   0)   {   
  receiveMsg   =   "";   
  for   (int   i   =   0;   i   <   len;   i++)   {   
  receiveMsg   +=   (char)   temp[i];   
  }   
  }   
    
  if   (receiveMsg.length()   >   0)   {   
  begin   =   receiveMsg.indexOf("Begin/");   
  end   =   receiveMsg.indexOf("/End");   
  if   (begin   >=   0   &&   end   >   0)   {   
  receiveMsg   =   receiveMsg.substring(begin   +   
  "Begin/".length(),   end);   
  if   (receiveMsg   !=   null   &&   receiveMsg.trim()   !=   ""   &&   
  receiveMsg.length()   >   0)   {   
  System.out.println(receiveMsg);   
  testCount++;   
  if   (!isTestConnectTime)   {   
  allDataLenght   +=   dataLenght;   
  }   
  }   
  }   
  }   
  //dos.close();   
  dis.close();   
  conn.close();   
  }   
  catch   (Exception   ex1)   {   
  System.out.println("Error   on   send   message");   
  ex1.printStackTrace();   
  }   
  }

 

分享到:
评论
1 楼 george_space 2011-07-29  
顶,非常好的文章。

相关推荐

    android studio Socket客户端服务器通信 TCP/IP通信

    android studio Socket客户端服务器通信 TCP/IP通信android studio Socket客户端服务器通信 TCP/IP通信android studio Socket客户端服务器通信 TCP/IP通信

    基于TCP/IP的socket编程

    实现了服务器与客户端功能的合二为一,客户端启动后,连接三次服务器,如果失败,则自己自动变为服务器。

    TCP/IP协议socket编程。学习资料

    TCP/IP协议socket编程。学习资料、、分客户端和服务器端

    基于局域网聊天程序设计其中网络通信部分采用流行的TCP/IP协议。程序采用典型的C/S(服务器/客户端)构架。用socket编程设计网络通讯

    其中网络通信部分采用流行的TCP/IP协议。程序采用典型的C/S(服务器/客户端)构架。用socket编程设计网络通讯。界面设计部分采用Windows MFC框架。数据库采用微软SQL Server。本文最终设计了一个简易版本的聊天软件,...

    基于TCP/IP协议的Socket服务器,实现点对点通信

    一个自己的小程序,适合初学者学习TCP/IP与Socket套接字的使用

    聊天室代码 TCP/IP SOCKET 通信

    完整的聊天室代码 支持多客户端请求! 基于TCP/IP SOCKET 的通信 资源包括:服务器和客户端 客户端连接服务后会返回信息,客户端和服务器能够互相发送信息,显示在界面上

    C# TCP/IP协议编写的客户端

    利用Socket (套接字)开发的客户端,可以与服务器通讯传输文件和字符。

    TCP/IP详解 卷3:TCP事务协议、HTTP、NNTP和UNIX域协议

    当客户与服务器进程在同一台主机上时,UNIX域协议通常要比TCP/IP快一倍。本书同样采用了大量的实例和实现细节,并参考引用了卷2中的大量源程序。适用于希望理解TCP/IP如何工作的人,包括编写网络应用程序的程序员...

    嵌入式TCP/IP协议栈源码

    嵌入式TCP/IP协议栈源码下载 1) 用户应用协议栈则需要编写以太网的数据报收发驱动,就可以使用协议栈提供的标准SOCKET API,完成服务器和客户端应用程序的开发。 2) 协议栈运行于非操作系统的环境下,因此它的运行...

    Android socket局域网的UDP广播自动连接及TCP/ip通讯与心跳检测

    简单的Android Socket ...客户端通过UDP广播获取到服务器端的IP地址,通过TCP/IP协议与服务器建立连接。代码实现心跳检测,当服务器断网或是结束进程,客户端可重新连接(重连部分自己实现);代码有点凌乱,仅供参考!

    TCP/IP网络编程基础知识

    网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机。数据传递本身没有多大的难度,不就是把一个设备中的数据发送给另外一个设备,然后接受另外一个设备反馈的数据。...

    C# 基于TCP/IP协议族的通信组件

    使用C#实现的一个C#通信组件,采用的协议是TCP/IP,服务器端开启服务后,可以接受客户端连接,可以同时多人在线,客户端可以给服务器发送消息,发送文件,服务器端可以给客户端发送消息和文件,并附加有实现的相应...

    TCP/IP测试工具

    1、TCP/IP测试工具分别为服务器端(SERVER)和客户端(CLIENT)的二个部分; ...3、操作系统需要安装TCP/IP协议; 4、SERVER和CLIENT可以在同一台计算机上使用; 此版本有一个BUG,请下载更新版,含代码

    Linux下基于TCP/IP协议的文件传输

    通过Linux C编程,设计一个基于TCP/IP的文件传输系统,实现服务器端和客户端之间网络文件的收发。

    嵌入式TCP/IP协议栈

    3.实现ARP协议、实现IP协议、实现ICMP协议、实现UDP协议、实现socket通信(与linux socket接口一致)、实现DHCP协议、实现DNS协议。4.能够将ping的结果通过串口输出,并能通过串口进行debug,从网络传递过来的应用...

    Socket网络TCP/UDP通信调试工具

    SocketTool调试工具最新版可以有效地帮助网络管理员检测各种网络通信状永久,集成了TCP服务器/客户端、UDP服务器/客户端和UDP广播/组播等功能。SocketTool调试工具官方版可以帮助网络编程人员、网络维护人员检查所...

    TCP/IP+socket网络编程

    简单的TCP协议上的socket编程,实现服务器端与客户端的简单交互

    SocketQQ_UDP_TCP/IP_服务器/客户端

    做了个类似QQ的局域网通信的测试软件,可以用UDP协议,也可以用TCPIP协议,功能基本都实现了,未详细整理,其中TCPIP的服务器和客户端地址在源程序里,控件上懒得做了。

    基于TCP/IP的网上聊天系统

    用C#(VS 2005平台)编写的基于TCP/IP的网上聊天系统(包括服务器和客户端),支持私聊和群聊,可以发送QQ表情图片,有仿QQ消息提示音,不同消息类型的字体颜色和背景色不同。

    C++使用SOCKET实现TCP-IP协议的通讯最好的DEMO源码

    第一个程序结构负责服务器的启动与客户端连接的登记,首先建立TcpListener网络侦听类,建立的时候构造函数分别包括localaddr和port2个参数,localaddr指的是本地地址,也就是服务器的IP地址,有人会问为什么它自己...

Global site tag (gtag.js) - Google Analytics