CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

简单服务器的实现-永久免费的源码丞旭猿

实现一个服务器,听起来是一件高大上的事情,然而,我们一样可以用Java代码实现它。

不过,在实现一个服务器之前,我们需要了解这几个指令和名词:

1、首先我们需要用到CMD中的一些指令

①:ipconfig:这个指令用来检查本机的IP地址

我们注意到上述图片中有许许多多的IP地址,到底哪个才是我们真正需要的呢?

我们可以打开网络共享中心,点击更改适配器设置找到网络连接。

右击状态

点击详细信息就会出现如下界面:

我们注意到:
而在cmd命令窗口中:
所以这无疑就是我们要找的地址。

那我们来了解一下各个地址之间的区别吧:

首先由于我们目前使用的IP V4协议的限制,现在IP地址的数量是有限的。这样,我们就不能为居于网中的每一台计算机分配一个公网IP。所以,在局域网中的每台计算机就只能使用私有IP地址了,如我们常见的192.168.0.*,就是私有IP地址。 而外网地址就是机器对外显示的网址,有网络运营商分配,电脑能自动获取,每台电脑都不一样。我们可以通过百度:IP地址查询,直接查询到自己的公网IP地址:

当然还有一个特殊的地址:127.0.0.1(回送地址) 它用来检查本地网络协议、基本数据接口等是否正常的。

其主要作用有两个:一是测试本机的网络配置,能PING通127.0.0.1说明本机的网卡和IP协议安装都没有问题;另一个作用是某些SERVER/CLIENT的应用程序在运行时需调用服务器上的资源,一般要指定SERVER的IP地址,但当该程序要在同一台机器上运行而没有别的SERVER时就可以把SERVER的资源装在本机,SERVER的IP地址设为127.0.0.1同样也可以运行。

它的别名就是localhost,当然localhost也就是指用户计算机本身。

现在,我们找到了自己的IP地址,这样就能搭建一个服务器了吗?答案当然是——NO!因为我们还需要一个东西:

2、端口(port):什么是端口?形象地来说的话,如果IP地址表示我们要寻找的房子的地址,那么端口就是这间房子的入口,一个IP地址的端口 可以有65536(即:2^16)个之多!端口是通过端口号来标记的,端口号只有整数,范围是从0 到65535(2^16-1)

我们都知道大多数操作系统是支持多线程操作的(即多个线程同时运行),那么目的主机应该把接收到的数据包传送给众多同时运行的进程中的哪一个呢?显然这个问题有待解决,端口机制便由此被引入进来。

本地操作系统会给那些有需求的进程分配协议端口(protocol port,即我们常说的端口),每个协议端口由一个正整数标识,如:80,139,445,等等。当目的主机接收到数据包后,将根据报文首部的目的端口号,把数据发送到相应端口,而与此端口相对应的那个进程将会领取数据并等待下一组数据的到来。说到这里,端口的概念似乎仍然抽象,那么继续跟我来,别走开。端口其实就是,操作系统为各个进程分配了不同的队,数据包按照目的端口被推入相应的队中,等待被进程取用,(在极特殊的情况下,这个队也是有可能溢出的),不过操作系统允许各进程指定和调整自己的队的大小。不光接受数据包的进程需要开启它自己的端口,发送数据包的进程也需要开启端口,这样,数据包中将会标识有源端口,以便接受方能顺利地回传数据包到这个端口。

当然 ,在CMD中我们可以用netstat -an:检查本机上已经使用过的端口号,来避免使用了使用中的端口。

说了这么多,那么在Java代码中怎么写呢?让我来细细道来:

在Java中实现通信的类有如下几种:

①Socket:Socket数据的通道,保持服务器与客户机连接的类

②ServerSocket:服务器Socket类

③InputStream:输入流

④OutputStream:输出流

⑤Thread或Runnable接口:线程

实现一个服务器,我们肯定需要一个客户机,这里的客户机使用CMD中的telnet命令打开系统自带客户机。

localhost为我们本机的IP地址(回送地址),后面的9999则是我们服务器的端口,所以现在我们可以写一个服务器啦!!!0-0

首先我们解释一下socket类:

通俗点说,它就是我们的客户机与服务器进行交流的通道,用来保持客户机与服务器之间的连接。

而ServerSocket类就是创建一个服务器连接:

也代表着我们的服务器。

当然,对于我们服务器这个程序来说,外部客户机的接入,发生和接收消息都需要通过IO流来完成。

完整代码如下:import java.io.IOException;

importjava.io.InputStream;importjava.io.OutputStream;importjava.net.ServerSocket;importjava.net.Socket;publicclassServerDemo{publicstaticvoidmain(String[]args)throwsIOException{ServerDemosd=newServerDemo();sd.create(6666);}publicvoidcreate(intport)throwsIOException{ServerSocketserver=newServerSocket(port);System.out.println("成功创建服务器,服务器端口号是"+port);System.out.println("服务器进入等待客户机连接......");}}

现在我们创建了一个服务器,运行如下:

在cmd上打开客户机:

在打开客户机之间,大部分电脑并没有开启telnet功能,所以我们需要先打开控制面板,点击程序。

选择启动或关闭Windows功能,将下面的复选框打勾

这样就能在CMD中使用telnet命令了。

现在我们使用客户机连接服务器:

为什么失败了呢,这是因为我们并没有建立服务器与客户机之间的连接socket。

修改代码如下:

importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.ServerSocket;importjava.net.Socket;publicclassServerDemo{publicstaticvoidmain(String[]args)throwsIOException{ServerDemosd=newServerDemo();sd.create(6666);}publicvoidcreate(intport)throwsIOException{ServerSocketserver=newServerSocket(port);System.out.println("成功创建服务器,服务器端口号是"+port);System.out.println("服务器进入等待客户机连接......");// 让server进入阻塞(等待)状态【等待客户机连接到服务器】,有客户机连接上来server就会返回一个Socket对象Socketsocket=server.accept();System.out.println("有客户机连接到服务器,客户机的IP地址与端口号:"+socket.getRemoteSocketAddress());}}

运行结果如下:

然后我们在用CMD打卡第二个客户机,连接:
我们发现现在只能连接一个客户机,而且客户机与服务器之间也完全没有交流。那么怎么办呢?

我们来分析,如果让服务器能连接多个客户机,则必须有一个队列来储存这些客户机,实际上我们用队列储存的不是客户机,而是对客户机的相关操作线程。这样我们每连接一个客户机就启动一个它对应的线程。是不是很完美呢?!0-0

所以我们修改代码如下:

importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.ServerSocket;importjava.net.Socket;publicclassServerDemo{publicstaticvoidmain(String[]args){ServerDemosd=newServerDemo();sd.createServer(9999);}/*** 创建服务器的方法** @param port服务器的端口号*/publicvoidcreateServer(intport){ServerSocketserver=null;try{// 实例化ServerSocket类的对象,指定portserver=newServerSocket(port);System.out.println("成功创建服务器,服务器端口号是"+port);System.out.println("服务器进入等待客户机连接......");while(true){// 让server进入阻塞(等待)状态【等待客户机连接到服务器】,有客户机连接上来server就会返回一个Socket对象Socketsocket=server.accept();System.out.println("有客户机连接到服务器,客户机的IP地址与端口号:"+socket.getRemoteSocketAddress());// 创建ChatMessage类的对象,将socket作为参数传递过去ChatMessagecm=newChatMessage(socket);cm.start();// 启动客户机的子线程对象。}}catch(IOExceptione){e.printStackTrace();}finally{// 关闭ServerSockettry{server.close();}catch(IOExceptione){e.printStackTrace();}}}}

然后我们新建一个线程类ChatMessage,其代码如下:

importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.Socket;publicclassChatMessageextendsThread{privateOutputStreamos;privateInputStreamis;privateSocketsocket;privateStringport;publicChatMessage(Socketsocket){this.socket=socket;try{// 获取socket中的输入流和输出流is=socket.getInputStream();os=socket.getOutputStream();}catch(IOExceptione){e.printStackTrace();}}publicvoidrun(){Stringstr=socket.getRemoteSocketAddress().toString();// 获取客户机的端口号port=str.substring(str.lastIndexOf(":"),str.length());// 让服务器向客户机发送一条消息sendMsg("欢迎"+port+"登陆简单服务器!\r");Stringmsg="";// 声明一个字符串对象// 读取消息,并且检测是否为bye\r(结束)while(!(msg=readMsg()).equals("bye\r")){System.out.println(port+"说:"+msg);sendMsg(msg);}close();}publicvoidclose(){// 关闭输入输出流、Sockettry{os.close();is.close();socket.close();}catch(IOExceptione){e.printStackTrace();}}publicStringreadMsg(){inti;StringBufferstr=newStringBuffer();try{while((i=is.read())!=10){str.append((char)i);}}catch(IOExceptione){e.printStackTrace();}returnstr.toString();}publicvoidsendMsg(Stringmsg){msg="服务器对"+port+"说:"+msg+"\n";try{os.write(msg.getBytes());}catch(IOExceptione){e.printStackTrace();}}}

首先,在这个类的构造方法中,我们实例化它的输入输出流,输入输出流都从它获取的socket对象中获得。接着是它的run方法。

String str = socket.getRemoteSocketAddress().toString();

// 获取客户机的端口号

port = str.substring(str.lastIndexOf(“:”), str.length());

这两句我们用来获得客户机的端口号,

然后使用sendMsg( )方法来让服务器向客户机发送消息。

调用输出流将变成字节的形式的消息发送给客户机。这里会抛出一个异常,需要捕获该异常。

当然我们还需要一个读取消息的方法readMsg( ):

由于append方法返回的是ascii值,所以我们要将它转换为char型。这个方法是String型的,这样能为我们返回这条消息。

最后我们需要一个close( )方法来关掉所有的输入输出流以及socket对象

当然,在run( )方法中,我们调用readMsg( )方法来判断输入字符串是否为bye,
如果为bye则while括号中变成false,退出该循环,否则继续发送消息和接受消息。

现在,我们这个简单的服务器已经全部完成啦,我们运行一下看看最终的效果吧:

但是,这依然只是一个雏形,下一次,我们让这两个客户机自己对话,并且拥有注册和登录的功能。

声明:本文部分素材转载自互联网,如有侵权立即删除 。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容