前言:该博客花了我一个下午得心血,全部手打,路过给个赞,拒绝抄袭!!!!!!!!!!!!!!!!!!!!!!!!!

简单的SOCKET通信程序

先从一段简单的JAVA程序性开始写起,这里我们才用半双工的形式,这里的半双工意思是客户端可以给服务端发送数据,发完数据就关闭,而服务端可以一直接受数据

我们使用多线程方式,这个不重要

下面是线程类

 public class SocketThread implements Runnable {
public SocketThread(Socket socket) {
this.socket = socket;
} private Socket socket;
@Override
public void run() {
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
try {
inputStream = socket.getInputStream();
inputStreamReader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
char buf[] = new char[1024];
int len=0;
while ((len=bufferedReader.read(buf))!=-1){
for(int i=0;i<len;i++){
System.out.print(buf[i]);
}
System.out.println();
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
inputStream.close();
inputStreamReader.close();
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

说实话,这个博客园的博客丑的一B,为什么不能提交CSDN的博客呢?

服务端代码:

 public class Server {
public static void main(String[] args) {
try{
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端已启动,等待连接");
while(true){
Socket socket = serverSocket.accept();
SocketThread socketThread = new SocketThread(socket);
new Thread(socketThread).start();
}
}catch (Exception e){
e.printStackTrace();
}
}
}

客户端代码:

 public class Client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost",8888);
OutputStream outputStream = socket.getOutputStream();
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
String str = scan.next();
outputStream.write(str.getBytes());
outputStream.flush();
}
}catch (Exception e){
e.printStackTrace();
}
}
}

分析

想要搞明白JAVA和LINUX之间的关系,首先你得明白我们的java代码编译成class文件后是运行在JVM上,这个CLASS字节码文件只有我们JVM认识,你扔给操作系统,操作系统铁定不懂。

JVM也是一个软件,它是由C++和C编写的,我们姑且认为它是C编写的,相信大家都看过JAVA源码,太多方法都是调用了native方法,比如我们的bind()方法

其次,JAVA的很多功能都是通过调用操作系统函数来实现的,比如显示文字

JAVA比如建立Socket是通过告诉虚拟机这个指令,然后虚拟机调用操作系统的Socket()函数来实现的

查看一下LINUX的SOCKET函数

简单说一下,第一个参数是域类型,看到IPV4选它就完事了,第二个参数是协议,我们用SOCK_STRAM表示TCP协议,第三个取0,0会把前两个参数对应起来,写0就完事了

return value是返回一个文件描述符,这个很难明白,你可以把它理解为我们JAVA里面的对象,JAVA当中有句话叫一切皆对象,而在LINUX中相应的我们叫做一切皆文件

只要我们拿到这个文件描述符,就能操作相应的Socket,牛逼吧= =

好的,下面讲一下验证思路

我们写一个JAVA方法,这个方法也调用NATVIE方法,而这个方法就不是JVM提供的C了,而是我们自己写的一个C文件,用这个C文件的函数调用操作系统内核函数来建立Socket连接,这里的StartServer()

方法就相当于我们之前的ServerSocket socket = new ServerSocket();如果能调用成功,是不是说明JAVA就是通过调用LINUX函数实现的呢?

正篇开始

先放代码

在我们JAVA中有socket.bind(),在C语言中怎么写呢?也是一样的,调用bind()函数即可,我们也来瞧瞧

第一个字段就是把我们刚刚的文件描述符传过来,第二个就比较复杂了我的哥,在C语言中我们的参数非常复杂,传入参数,传出参数和传入传出参数

啥意思?其实很简单,传入参数就是传进来修改不会影响外面,类似局部变量,。。。传入传出就是指针啥的嘛,我们这里就是结构体指针,但是如果加了一个const就不一样

const 意思是我们不能修改它即只能传入,不能传出

这个sockaddr 结构体里面有两个参数,一个是IP,一个是端口号PORT,就是IP+端口,最后是你结构体的长度

看正篇最开始的代码,为什么我这里写的是sockaddr_in呢?参数不是sockaddr嘛?你可以把这个理解为JAVA当中的类型,人家要一个INT结果你传一个字符串

这个其实是在UNIX开发之初,我们的IP协议还没有很稳定的时候是用sockaddr来描述的,但是随着计算机的发展,IP协议越来越复杂,所以它开发了另一个函数叫Sockaddr_in来表示我们的IP和端口号,所以这个方法已经过时了,但是为什么没改掉呢?这个很简单啊,和JAVA一样它在很多地方都有使用,你不能随便改,就像JAVA一样我们都是声明接口,传入实现类等等保障系统的可扩展性。那怎么办?其实很简单,我们传一个参数进来然后把它强转成这个类型不就好了

这个htons是啥?这个叫本地转换成网络字节数,短整型,说白了,你这个8080人家LINUX不认识,你需要通过转换。比如你传一个192.168.。。。人家LINUX不认识,它需要把它转换成123456的整形才认识,这就是提供转换的函数

INADDR_ANY是啥,你也可以换成localhost,这里表示当前本机任何一个可用的IP地址

这个listen是监听你当前Socket当中在同一时刻能够接受的连接数,它默认值是128,无所谓,他不是关键

这是啥?传出来的是C语言类型的数据,不是我们能看懂的IP等,我们需要转换一下,就转到这个数组中

这个就是读数据啊,读到这个字符串数据里,以及它的长度

关键

这里涉及JNI调用,不懂得自己去看吧。关于什么是JNI我就不解释了

首先来段简单代码,这个conn()会调用到我们自己写得C方法,注意你的包名设置,等会编译的时候需要你到你LINUX目录的上一级目录编译 com.类名

把这个JAVA文件拷贝到LINUX系统里

然后编译这个java文件成.h文件,这里注意你的JDK环境设置,我一开始用的是OPEN JDK是没有JAVAC命令的

关键来了,我们查看我们编译好的.h文件

然后这个.h文件可以在我们写的函数里导入进来那我们那个方法怎么命名,参考.h文件,这个.h中生成了一个conn()方法的C语言调用连接

这个JNIEXPORT。。。就是我们得调用函数名称,替换C文件得方法名即可

你可以把这个方法看成conn()方法在LINUX下的名称,等会调用conn()方法等于调用这个方法

注意一下,你必须指定你的classpath路径,否则我们得java System.loadLibray是找不到得,很简单得道理,你写JAVA得时候你在当前目录下得文件,你要JAVA怎么运行呢?

还有就是必须导入/include和/include/linux下的两个头文件,参考我上面的命令

哈哈哈,可以看到我们运行JAVA已经调用到LINUX下得内核函数了,下面来测试一哈

牛逼吹完了,看看效果

这个nc是用来模拟连接得,可以直接通信了,哈哈哈

证明成功!

总结:好累啊,再也不想这么认真写实验了= =。写了一个下午,我要去划水

JAVA网络通信底层调用LINUX探究的更多相关文章

  1. 如何在java程序中调用linux命令或者shell脚本

    转自:http://blog.sina.com.cn/s/blog_6433391301019bpn.html 在java程序中如何调用linux的命令?如何调用shell脚本呢? 这里不得不提到ja ...

  2. java程序中调用Linux命令Windows命令

    目前总结的方法: 调用Linux简单的命令行,设置文件夹权限755 String scriptDir = "/home/wenf"; String cmd = "chmo ...

  3. JAVA Socket API与LINUX Socket API探究

    代码 这是一个带有UI界面的JAVA网络聊天程序,使用Socket连接完成通信. JAVA服务端程序 import java.io.IOException; import java.io.InputS ...

  4. java调用Linux命令报错:java.io.IOException: Cannot run program "ps": CreateProcess error=2, ?????????

    在idea里面,java代码:Runtime.getRuntime().exec("ps -aux") 是因为默认是用windows平台运行了,所以报错,得改成调用Linux平台运 ...

  5. java远程调用linux的命令或者脚本

    转载自:http://eksliang.iteye.com/blog/2105862 Java通过SSH2协议执行远程Shell脚本(ganymed-ssh2-build210.jar) 使用步骤如下 ...

  6. java调用Linux执行Python爬虫,并将数据存储到elasticsearch--(环境脚本搭建)

    java调用Linux执行Python爬虫,并将数据存储到elasticsearch中 一.以下博客代码使用的开发工具及环境如下: 1.idea: 2.jdk:1.8 3.elasticsearch: ...

  7. Java调用Linux命令(cd的处理)

    一.Java调用Linux系统的命令非常简单 这是一个非常常用的调用方法示例: public String executeLinuxCmd(String cmd) { System.out.print ...

  8. java调用linux下的so库

    1.编写java类 public class Abc { static { System.loadLibrary("abc"); } public native static St ...

  9. Java调用Linux命令执行

    调用方式 Java调用linux命令执行的方式有两种,一种是直接调用linux命令,一种是将linux命令写到.sh脚本中,然后调用脚本执行. 详细说明 直接调用:使用java中lang包下面的Run ...

随机推荐

  1. 使用haproxy实现负载均衡集群

    一.HAProxy概述: HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.根据官方数据,其最高极限支持10G的并发. HAP ...

  2. 随机数产生器:Random.Next

    Random类是一个产生伪随机数字的类,它的构造函数有两种,一个是直接New Random(),另外一个是New Random(Int32),前者是根据触发那刻的系统时间做为种子,来产生一个随机数字, ...

  3. 解决node.js使用fs读取文件出错

      今天配接口,使用fs模块读取json出现了错误'no such file or directory',然后经查终于解决,特此记录. 使用nodejs的fs模块读取文件时习惯用相对路径,但是运行的时 ...

  4. Mongo 导出为csv文件

    遇到需要从Mongo库导出到csv的情况,特此记录. 先贴上在mongo目录下命令行的语句: ./mongoexport -h 10.175.54.77 -u userName -p password ...

  5. 【XSY2344】K-th String

    Description Alice有 n(n≤26) 张牌,牌上分别标有前 n 个英文小写字母.例如,如果 n=3 ,则Alice有3张牌,分别标有"a", "b&quo ...

  6. 如何做seo优化才能获取搜索引擎排名?

    现在网络上有很多网站,但是排名和流量都不理想,所以很多企业会很苦恼.所以我们经常思考如何使网站被搜索引擎喜欢,被用户喜欢,有一个良好的排名和流量? 在这个鱼龙混杂的网络中,seo优化实际上是seo网站 ...

  7. 入门Android底层需要的一些技能

    <Android的设计与实现> Android框架层<Linux系统编程手册> Linux系统编程<Android内核剖析> 编译框架和romC语言和Linux内核 ...

  8. NOI导刊总结

    NOI导刊总结 前两天去郑州,参加了什么NOI导刊的培训,然后就发现大佬是真的多,还十分意外的发现了一个事,清华北大是不是发笔记本和耳机,为啥三个老师的都一模一样... 这几天主要以讲.NOIP知识点 ...

  9. Python - selenium自动化-Chrome(headless)

    什么是 Headless Chrome Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序.相比于现代浏览 ...

  10. Jenkins+JMeter+Ant 接口持续集成

    ​JMeter安装 JMeter安装包: 下载地址:https://jmeter.apache.org/download_jmeter.cgi 依赖JDK环境 JDK环境配置: JAVA_HOME   ...