您的位置:首页 > 编程语言 > Java开发

java通信&套接字Socket

2016-03-06 21:29 351 查看
无论用什么语言开发,socket都是绕不过去的一个环节,若以简单论,除了文件操作,进程间通过socket通信还是比较方便的。

socket原理:

对于主机a和b,若a主机想向b主机发送信息,那么基本步骤如下:

1. 首先确保b主机上socket服务端开启,服务端会监听本机上的一个端口,例如8080。socket服务端会以阻塞形式启动,直到有客户端连接该端口。

2. 主机a需事先知道主机b的ip地址(假设为192.168.1.2),以及服务端监听的端口号,然后建立一个指向192.168.1.2:8080的连接,此时若主机a和b无其他外部条件影响,则socket已完成。

3. 主机b上的服务端在监听到本机的8080端口被连接后,阻塞就停止了,会按照设计向下执行命令。

对于服务端ServerSocket和客户端Socket来说,都可以通过getXXX的方式获取套接字的输入流和输出流。数据以流的形式进行发送时,客户端可能连续发送了很多次数据,而服务端会一次性将所有数据读取完毕,因此若信息要求分开发送,则最好约定分隔符。

服务端监听:

void openServerSocket(final int port){
//socket服务端是会阻塞线程的,因此一定要开新线程。
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
//新建服务端Server
ServerSocket server=new ServerSocket(port);
//服务端监听等待时间,时间超过将不再监听端口
server.setSoTimeout(30000);
//在30秒内,确保服务端会一直可以监听端口,即便有客户端退出也会回到监听状态。
while(true){
//accept方法会阻塞线程,知道有客户端连接
Socket client=server.accept();
//client.setKeepAlive(true);
//获取客户端的主机名
String name=client.getInetAddress().getHostName();
Log.d("服务端----监听到:"+name);
//设置该线程的级别,保证优先运行该线程
Thread.currentThread().setPriority(9);
//获取到socket的输入流,可以读取从客户端发来的信息。(注:这里约定发送的信息都是字符串,若是文件形式,则不可以用reader方式读取数据,否则会造成数据缺失)
BufferedReader reader=new BufferedReader(new InputStreamReader(client.getInputStream()));
String line="";
String str="";
while((line=reader.readLine())!=null){
str+=line;
}
Log.d(name+":"+str+"\n");
//将获取到的字符串发给客户端,让客户端可以判断服务端是否成功接收到了数据。

BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
writer.write(str);
writer.flush();
client.close();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//若端口未监听成功或出现异常,则直接关闭程序
System.exit(0);
}
}
}).start();
}


代码很简单,主要过程就是:监听端口port,如果有客户端连接,那么accept方法就会停止阻塞,服务端会读取从客户端发来的数据,然后将该数据再次发送给客户端。

客户端连接:

void openClientSocket(final String information,final String serverSocketName,final int port){
//进行耗时操作需另开线程
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try{
//建立到服务端serverSocketName:port的连接
Socket client=new Socket(serverSocketName, port);
//一定要设置连接超时,否则万一服务端或者路径有问题,会导致程序卡死
client.setSoTimeout(2000);
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
writer.write(information);
writer.flush();
//这一行代码特别重要,客户端在流的方向改变时,必须中断上一个流,否则程序会崩溃的。
client.shutdownOutput();
BufferedReader reader=new BufferedReader(new InputStreamReader(client.getInputStream()));
String line="";
String str="";
while((line=reader.readLine())!=null){
str+=line;
}

//去除回车等符号的影响
if(str.replace("\n", "").equals(information.replace("\n", ""))){
Log.d("客户端---数据发送成功");
}else{
Log.d("客户端---数据发送失败");
}
client.close();
}catch (Exception e1) {
// TODO Auto-generated catch block
Log.d("客户端---服务器无法连接");
}
}
}).start();
}


服务端与客户端代码都很简单,因此不要以为进程间通信很难,都是已经封装好的内容,直接使用就可以了,利用此功能可以自己写聊天室等等。

replace和replaceAll的区别

socket工作原理

c语言实现socket通信
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: