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(); 
} 
}

转载 http://topic.csdn.net/t/20060918/23/5030821.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个服务器对多个客户端的MFC Socket编程示例(实现简单的即时通讯功能) 环境:Windows XP SP3、 VC++ 6.0、 Windows 2003 SDK 使用步骤: 1、下载解压之后,使用VC++ 6.0打开两个工程:一个是SocketServer和一个ClientSocket工程。 2、首先运行服务器端工程,选默认的端口1008 3、然后运行客户端工程,选默认的端口1008和默认的服务器地址 4、再运行多个客户端进程 5、如果一切正常,可以每个客户端的消息发送,我们可以在服务端和各个客户端同步看到消息 实现一个服务器对多个客户端的关键是,在服务端的使用集合CPtrList类用保存客户端socket对象,思想与Java中的编程思想一样,只不过Java中会使用多线程技术,在Vector集合保存客户端socket对象 ,而MFC框架提供了CSocket类,它是一个异步通信的类,所以看上去代码比较Java的多线程代码简单的实现了一个对多的即时通讯功能。另外,MFC提供了CSocketFile类和CArchive类与CSocket类实现了C++的网络通讯编程功能。 本示例注释非常详细,所有的辅助类都放一个util目录中,然后在工程中分了一个目录来管理这些辅助类,使用代码非常清晰。手动书写部分的代码是按Java的规范书写,当然其它代码由IDE生成的,所以是MS的风格,所以当你看代码时,只要是使用“骆驮命名法”的方法都是本人书写的功能性代码。 参看的思路:在服务端要从回调方法onAccept读起;而客户端代码主要从OnSendButton方法读起,即可理解整个代码的意思。 阅读对象:具有JavaSocket编程经验的人员,并且希望能够书写出比Java效率更高的即时通讯程序的人员
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值