java的Scoket通信_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java的Scoket通信

java的Scoket通信

 2015/1/27 4:03:02  hm4123660  程序员俱乐部  我要评论(0)
  • 摘要:Scoket服务端建立:packagecom.Scoket.Test;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.ServerSocket;importjava.net.Socket;publicclassServerScoket{publicstaticvoidmain(String[]args){ServerSocketss=null;Sockets=null;try
  • 标签:Java

Scoket服务端建立:

package com.Scoket.Test;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerScoket {
?? ?public static void main(String[] args) {
?? ??? ?ServerSocket ss=null;
?? ???? Socket s=null;
?? ??? ?
?? ???? try{
?? ???????? ss=new ServerSocket(6000);//创建一个ServerSocket在端口监听客户请求--端口
?? ??????? ?
?? ????????? //能接受多个----加上while和线程实现多连接
?? ???????? while(true)
?? ???????? {
?? ??? ???????? s=ss.accept();//accept()是一个阻塞的方法,一旦有客户请求,它就会返回一个Socket对象用于同客户进行交互? ??? ????????
?? ??? ???????? //每接收到一个Socket就建立一个新的线程来处理它 ?
?? ??? ???????? new Thread(new Task(s)).start(); ?
?? ???????? }????
?? ???????? //ss.close();//关闭服务端
?? ?????? }
?? ?????? catch(Exception e)
?? ?????? {
?? ???????? e.printStackTrace();
?? ?????? }

?? ?}
?? ?
?? ?/**
?? ???? * 用来处理Socket请求的
?? ???? */ ?
?? ??? static class Task implements Runnable { ?
?? ?? ?
?? ?????? private Socket socket; ?
?? ??????? ?
?? ?????? public Task(Socket socket) { ?
?? ????????? this.socket = socket; ?
?? ?????? } ?
?? ??????? ?
?? ?????? public void run() { ?
?? ????????? try { ?
?? ???????????? //处理客户端请求
?? ??????? ??? ?OutputStream os=socket.getOutputStream();//输出流-------传给客户端的数据
?? ? ?? ???????? InputStream is=socket.getInputStream();//输入流---------获取客户端的数据
?? ? ?? ???????? os.write("hello world!!!!!".getBytes());//输出流向客户端发送数据
?? ? ?? ???????? //读取客户端数据
?? ? ?? ???????? byte[] buf=new byte[100];//每次读取的字节大小为100
?? ? ?? ???????? int length=is.read(buf);
?? ? ?? ???????? System.out.println("来自客户端数据:"+new String(buf,0,length) );
?? ? ?? ???????? os.close();//关闭输出流
?? ? ?? ???????? is.close();//关闭输入流
?? ? ?? ???????? socket.close();//关闭客户端连接
?? ????????? } catch (Exception e) { ?
?? ???????????? e.printStackTrace(); ?
?? ????????? } ?
?? ?????? }
?? ??? }

}

客户端代码实现----主要介绍数据怎么接收,客户端接收的数据是:hello world!!!!!

package com.Scoket.client;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientScoket {
??? public static void main(String[] args) {
??? ??? ?try{
??? ??? ????? Socket s=new Socket("172.18.13.116",6000);//创建客户端套接子
??? ??? ????? OutputStream os=s.getOutputStream();//输出流-----发送给服务器
??? ??? ????? InputStream is=s.getInputStream();//输入流-----得到服务端数据

?

????????????? //开始接收数据部分
??? ??? ????? byte[]buf=new byte[5];//每次读取的字节数大小---现在只读5个字节?? ????
??? ??? ????? int len=is.read(buf);//read(byte[] b)方法提供了一个返回的整数用来表示接受了多少个字符。
??? ??? ????? System.out.println(new String(buf,0,len));//----直接收5个字符,所以是:hello
??? ??? ?????
??? ??? ????? byte[]buf1=new byte[6];?? //每次读取字符数 ? ????
??? ??? ????? int len1=is.read(buf1);//会接着上一次继续读取
??? ??? ????? System.out.println(new String(buf1,0,len1));//接着读取6字符,所以是:? world,有个空格

????????????? //-------------------------数据接收完成

????????????? //发送给服务器
??? ??? ????? os.write("this is fan".getBytes());
??? ??? ????? os.close();
??? ??? ????? is.close();
??? ??? ????? s.close();
??? ??? ?????
??? ??? ??? }catch(Exception e)
??? ??? ??? {
??? ??? ????? e.printStackTrace();
??? ??? ??? }

??? }

}

运行效果:



?若把这部分改成----成功接收,但不采纳,因为无法确定传来的是多少字节

? //开始接收数据部分
??? ??? ????? byte[]buf=new byte[100];//每次读取的字节数大小---现在读100个字节,大于总字节可以一次接收完
??? ??? ????? int len=is.read(buf);//read(byte[] b)方法提供了一个返回的整数用来表示接受了多少个字符。
??? ??? ????? System.out.println(new String(buf,0,len));//----直接所有字符,所以是:hello world!!!!!
? //-------------------------数据接收完成

?

若改为:

//开始接收数据部分
??? ??? ????? byte[]buf=new byte[20];//每次读取的字节数大小---大于总字节,读取完成 ? ????
??? ??? ????? int len=is.read(buf);//read(byte[] b)方法提供了一个返回的整数用来表示接受了多少个字符。
??? ??? ????? System.out.println(new String(buf,0,len));//
??? ??? ?????
??? ??? ????? byte[]buf1=new byte[6];?? //每次读取字符数 ? ????
??? ??? ????? int len1=is.read(buf1);//会接着上一次继续读取----------程序会在这里阻塞
??? ??? ????? System.out.println(new String(buf1,0,len1));//接着读取6字符,所以是:? world,有个空格? //-------------------------数据接收完成

?

不知到为何用上面的is.read(buf)阻塞,好像是它一直等待数据到满才返回,所以用

byte chars[]?=?newbyte[64];??
??????int?len;??
??????StringBuffer?sb?=?new?StringBuffer();??
??????while?((len=reader.read(chars))?!=?-1)?{??
?????????sb.append(new?String(chars,?0,?len));??
??????}?

也会阻塞,这行代码上面。这就是在网络应用中会造成的后果。那么如何解决呢?有的人给出了如下代码:

?

目前我个人发现最好方法就是

???????????? int count = 0;

??????????? //调用available()方法时,对方发送的数据可能还没有到达,你得到的count是0。??? ??? ?????

???????????? while (count == 0) {
??? ??? ????? count = is.available();//获取字节长度
??? ??? ????? }
??? ??? ????? byte[] b = new byte[count];
??? ??? ????? int len=is.read(b);
??? ??? ????? System.out.println(new String(b,0,len));

?

?

?

?

关于InputStream.read(byte[] b)和InputStream.read(byte[] b,int off,int len)这两个方法都是用来从流里读取多个字节的,有经验的程序员就会发现,这两个方法经常 读取不到自己想要读取的个数的字节。比如第一个方法,程序员往往希望程序能读取到b.length个字节,而实际情况是,系统往往读取不了这么多。仔细阅 读Java的API说明就发现了,这个方法 并不保证能读取这么多个字节,它只能保证最多读取这么多个字节(最少1个)。因此,如果要让程序读取count个字节,最好用以下代码:

Java代码 ? int?count?=?100;??
byte[]?b?=?new?byte[count];??
int?readCount?=?0;?//?已经成功读取的字节的个数??
while?(readCount?<?count)?{??
????readCount?+=?inStream.read(b,?readCount,?count?-?readCount);??
}?

?

?

?

  • 大小: 6.1 KB
  • 查看图片附件
上一篇: 什么是RESTful风格 下一篇: 没有下一篇了!
发表评论
用户名: 匿名