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;???
?