您的位置:首页 > 理论基础 > 计算机网络

网络通信(一):简单的聊天程序

2015-02-01 16:54 363 查看
数据在网络中是以流的形式传输的,流里面是字节的形式在传递,这里以简单的聊天程序看看网络通信。

在写创建服务器的方法时,需要明白两个词的含义,一个是IP,一个是端口(port)。客户端是通过IP找到服务器(服务器运行程序所在的计算机)在网络中的位置,而port是标识程序在计算机上的位置。(在CMD中可以通过“netstat -ano”查看程序端口号)IP是已经指定好的,所以我们创建服务器时需要指定端口号,代码如下:

<span style="font-size:18px;">/**
* 创建服务器
* @param port  绑定程序的端口
* @return   服务器对象
*/
public  ServerSocket  createServer(int port){
ServerSocket server=null;
try {
//在指定的端口上创建服务器对象
server = new ServerSocket(port);
System.out.println("服务器已经创建。。。。");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return server;
}</span>
注意:这里定义server时需要赋值,因为try-catch可能无法进入,不赋值无法返回

接着写侦听客户端连接,代码如下:
<span style="font-size:18px;">/**
* 侦听客户端
* @return  服务器与客户端之间的连接通道
*/
public  Socket  listenClient()  throws IOException{
//创建通信的连接通道
Socket connect=null;
//创建服务器对象
ServerSocket  server= createServer(9090);
//侦听客户端,获取连接通道
connect=server.accept();
//String remote_ip = connect.getRemoteSocketAddress().toString();
 String remote_ip=connect.getInetAddress().toString();
System.out.println("IP为"+remote_ip+"的客户端已连接。。。。。");
return  connect;
}</span>
接下来,新建一个Test类进行测试,代码如下:
<span style="font-size:18px;">public class Test {

public static void main(String[] args) throws IOException{
Server test_server=new Server();
test_server.listenClient();
}

}</span>
程序一运行,后台就会打印“服务器已创建。。。。”此时程序阻塞在侦听连接的accept方法处,因为还没有客户端,所以使用命令行来模拟。(命令行中的telnet是微软自带的客户端程序,使用:telnet+空格+ip+空格+端口,例如:telnet
www.baidu.com 80就可以连接到百度服务器,输入:“telnet localhost 9090”,回车后程序正常运行,



可见方法无误,已经侦听到客户端,继续接收/发送数据的方法,开始聊天,代码如下:
<span style="font-size:18px;">/**
* 聊天
* @param connect  服务器与客户端之间的连接通道
*/
public  void chat(Socket connect){
try {
//从连接通道上获取输入(接收)、输出(发送)流对象
InputStream  in=connect.getInputStream();
OutputStream out =connect.getOutputStream();
String s="hello! \r\n";  //回车换行,避免覆盖
//打招呼:字符串变字节数组输出
out.write(s.getBytes());
} catch (Exception e) {
// TODO: handle exception
}
}</span>
在测试类Test的代码中,调用聊天方法,运行,再使用cmd连接,就可以在cmd中接收到打招呼信息:“hello!”。此时服务器只有收信息方法,运行完就断开,cmd接收到消息后就会遗失的主机的连接。下面添加服务器接收消息的方法。代码如下:
<span style="font-size:18px;">//输入流读取客户端的消息  此处读到的为ASCII值
int i=in.read();
while(i!='#'){   //定义通讯规则,遇到#字节就停止
System.out.print((char)i);   //char强转字符
i=in.read();
}
</span>
然后运行服务器,在cmd中发送消息,可以看见程序不会结束,在服务器这边也接收到消息(随机输入的字符)



下面重写聊天方法,实现基于控制台的客户端和服务器的简单聊天。注意这里是单线程,是按“服务器发,客户端收;客户端发,服务器收”的顺序进行聊天,代码如下:

//发消息
System.out.println("服务器说:");
//创建从系统输入流扫描的扫描器
Scanner scan=new Scanner(System.in);
//扫描
String line=scan.nextLine();
//得到输入值长度
String length=line.getBytes().length+"";
//将长度和输入值加空格拼接成消息
String msg=length+" "+line;
//发送消息
out.write(msg.getBytes());
//收消息
String len="";
int i=in.read();
while(i!=32){   //定义通讯规则:遇到空格就停止
//计算输入的长度
len+=(char)i;
i=in.read();
}
int l=Integer.parseInt(len);
//创建输入值长度的字符数组
byte[] array=new byte[l];
//将输入值读取并缓存到array数组
in.read(array);
String m=new String(array);
System.out.println("客户端说:"+m);


后台聊天界面:


这里Test测试类,使用
while(true){
test_server.chat(connect);
}
使得程序一直等待双方聊天中
不过,程序有一处问题,如图,在控制台输入时,只能另起一行输入(标记②处),这样可以正常聊天,如果从①处写,扫描器就会读错,


后面学习继续,代码会继续改进。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: