java socket-客户端接收不到服务端口消息问题原因

初步尝试了解下socket编程,结果被一个问题困扰了一天,回想真是失败~总结原因
1 明显的java功底太弱,对各种类的了解不彻底深入
2 解决问题的方法不够理性,系统~

陈述问题,最简单的情况,单线程交互,问题代码如下:
server:

package sl.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class BugServer {

public static void main(String[] args) {
ServerSocket ss = null;
try {
ss = new ServerSocket(10000);
System.out.println("server start...");
while(true){
Socket socket = ss.accept();
System.out.println("a client come in :"+socket.toString());

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//注意:if true, the println, printf, or format methods will flush the output buffer
//即使autoflush了,也只对三个方法有效!
PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);


//若客户段没有使用autoflush方法,服务段将阻塞在这一行
System.out.println(in.readLine());
//问题出在这里,调用的不是autoflush的方法,即使后面有 pw.flush() 也不行!
pw.println("服务端反馈! to "+ socket.toString());
pw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


client:

package sl.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class BugClient {
Socket soc;

public static void main(String[] args){
new BugClient().send();
}

private void send() {
try {
soc = new Socket("127.0.0.1",10000);
PrintWriter socOut = new PrintWriter(soc.getOutputStream(),true);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
BufferedReader netIn = new BufferedReader(new InputStreamReader(soc.getInputStream()));

String line = in.readLine();
System.out.println("input: "+line);
// 若使用了非 autoflush方式,即使显示flush的话,更是连服务端都收不到消息!

//由于消息没有"立即"传输到服务端, 会使得server在 阻塞在 in.readline()那一行.
socOut.print(line);
socOut.flush();

//若将此行注释掉,即客户段放弃接收服务段消息,
//那么这个客户段程序可以跑完,服务端将接收到消息,造成 socOut.flush()好像立即起了作用的假像
//实际上,并不是 flush()那行代码起了作用,而是程序结束时,对 out流做清理工作,使得消息最终发送了过去
/**
* 启用一下两行代码,由于 服务段已经被阻塞了,更别说响应,则客户段将阻塞在 netIn.readline();
*/
System.out.println(netIn.readLine());

soc.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


就这样一个问题困扰了我一天,虽然最终发现了问题所在,也可以解决问题,但是理解上还没有透彻。
依然的困惑:
1 流的传输中flush的机制到底是怎样的,为什么显示的调用flush()都没有效果,又为什么放弃了客户段接收信息,程序结束时,消息最终还是传向了服务端?
2 socket的内部机制,在javaeye看帖时看到一句话,算是识记了这个知识,但不理解
“[color=darkred]Socket的发送与接收是需要同步进行的,即客户端发送一条信息,服务器必需先接收这条信息, 而后才可以向客户端发送信息,否则将会有运行时出错。[/color] ”

感叹一些自己的java如此单薄~

[size=large][size=medium][color=darkred]今天又看了一些资料,发现以上理解全部错了~ 阻塞的真正原因是因为 readline()一直在寻找 换行符号"\n",而根本就不是flush的原因![/color][/size][/size]
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java聊天室的设计与实现socket 设计软件源码+WORD毕业论文文档 Java聊天室系统主要用于实现在线聊天,基本功能包括:服务端客户端。本系统结构如下: (1)服务端: 1、能够开启和关闭服务器 2、等待着客户端从特殊端发送的请求 3、监听的端并不是固定的,服务端的端是能够自定义的 4、能够广播消息向所有连接到服务器的用户 (2)客户端: 1、能够和服务端进行连接 2、新的用户能够注册账号 3、通过用户名以及密码完成用户的登陆,连接到聊天室 4、用户能够在聊天室发送消息 目 录 摘要 I Abstract II 目 录 III 1 引言 1 2 网络聊天室的简介 2 2.1网络聊天室现状和发展 2 3 完成网络聊天室的技术以及环境 4 3.1 Java的介绍 4 3.2 Java的特点 4 3.3 TCP/IP协议的知识 5 3.4 Socket的介绍 6 3.5 开发工具 6 4 网络聊天室系统的设计 7 4.1项目概述 7 4.2 网络聊天室系统的设计 7 5 系统详细设计 8 5.1 服务器模块的设计 8 5.2 客户端模块的设计 8 6 系统测试 9 6.1 单元测试 9 6.2 系统测试 9 7 总结 10 参考文献 11 致谢 12 1 引 言 随着社会的发展和互联网技术的发展,普通老百姓也能够拥有属于自己的计算机,在平常的生活中也离不开了网络技术的支持,而替代了电话和写信的网上即时聊天成为了人们十分常见的沟通方式。 本软件是采用sun公司开发提供的java语言制作的,是基于C/S模型的网上聊天室。这个系统分为两个部分,服务端客户端服务端工作主要是来监听和接收来自客户端的请求,然后处理客户端发来的消息,并通知客户端。而客户端的功能是能够让新用户注册,通过用户名密码登陆并且使用该系统。通过服务端客户端的协同工作最终使用户能够使用网络聊天室,在聊天室中完成用户和用户之间的沟通。 2 网络聊天室简介 当今社会,能够实现即时通讯的软件使用频率是十分恐怖的,网络聊天室作为它的一种,使用人数也是相当可观的。国内处于垄断的QQ,业界老大哥微软的MSN都是大众关注和使用的焦点,普通老百姓也能够拥有属于自己的计算机,在平常的生活中也离不开了网络技术的支持,它是人们的生活变得十分的便利和高效,你能在网上找到自己想要的信息和有共同兴趣爱好的朋友。而且,现在很多的软件还有多人聊天,电子会议等一系列功能。 2.1 网络聊天室现状和发展 网上即时聊天室是广泛使用的一种技术,它的简单方便的沟通方式能够被广大的网上用户所使用。在当今社会,网上聊天是互联网服务重要的一环,有大约43%的用户都会使用网上聊天,是排在第四位。但是有很多人认为网络聊天室就是一种用来娱乐和打发时间的方式,而缺少了实际的价值。就目前来说,能够完成收入的网络聊天室其实并不多。它应该怎么实现自己的商业价值外界并没有过多的关注。 现在,很多企业都会开发属于自己的聊天室,用户通过该网站注册的用户名以及密码登陆到企业的服务器上。在聊天室中,用户之间可以通过输入文字以及各种符号来表达自己的想法,来达到互相之间的沟通。目前,开发一个供用户使用的网络聊天室的技术门槛并不是很高,也不需要大量的资金,国家对于这方面的管制和政策也没有太限制,所以当今社会上聊天室的竞争其实是很激烈的,腾讯,网易,新浪都有属于自己的网络聊天室
基于Java的视频会议系统(软件程序+WORD论文文档) 2.1.1 技术可行性 网络视频会议是顺应市场的需求而设计的。采用JAVA 编程语言,用eclipse开发平台实现。用到多媒体技术(JAVA 多媒体框架JMF),视频和音频用TRP协议传输,用到Socket编程技术,多播技术。网络视频会议首先是基于网络传输的,那么就必然要依托于JAVA网络编程的相关知识。在这基础上,由于相关音频、视频,所以还要涉及到JAVA的多媒体技术的相关知识,即JMF (Java Media Framework)。利用JAVA的这个组件,我们可以方便的处理多媒体文件,并基于RTP协议进行实时传输。 2.1.2 操作可行性 系统运行于Windows环境,其用户操作界面友好,便于操作,适合视频会议流程。 系统的基本操作如下: 1.启动服务器; 2.用户连接到服务器; 3.进行视频连接; 4.举行会议; 5.会议完毕,退出系统。 2.2 采用的关键技术介绍 2.2.1 JAVA多媒体技术 JAVA多媒体技术的核心是Java媒体框架 JMF(Java Media Framework)。JMF中包含了许多用于处理多媒体的API,它是一个很好的多媒体编程工具,同时也是一个相当复杂的系统。JMF的主要应用功能之一是多媒体数据流在网络中的实时传输,其RTP包中提供的RTP包中提供的RTPManager(RTP管理器)、TrackContol(轨道控制器)、SendStream(发送数据流)、ReceiveStream(接收数据流)、InetAddress(IP地址)和SessionAddress(会话地址)等类使得编写网络实时数据传输变得容易,基于RTP协议的RTP应用程序框架为实现流媒体在网络中实时传输提供了Java程序框架,应用它可方便的实现多媒体数据流在网络中的实时传输。实时传输协议RTP是在Internet网上针对多媒体数据流的一种传输协议,RTP被定义为在一对一获一对多的传输情况下工作的,其目的是提供时间信息和实现多媒体数据流的同步。RTP由RTP和RTCP(实时控制协议)两个部分组成。RTP本身并不能为按顺序传送数据包提供可靠的传送机制,可不提供流量控制或拥塞控制,它依靠RTCP提供这些服务。 2.2.2 JAVA 网络编程技术 网络编程的目的就是指直接或间接地通过网络协议与其他计算机进行通讯。网络编程中有两个主要的问题,一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。而TCP层则提供面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。   目前较为流行的网络编程模型是客户机/服务器(C/S)结构。即通信双方一方作为服务器等待客户提出请求并予以响应。客户则在需要服务时向服务器提出申请。服务器一般作为守护进程始终运行,监听网络端,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端,使后来的客户也能及时得到服务。 数据在Internet中是以有限大小的包形式传输的,这些包称为数据报(datagram).但是,由于数据报长度有限,通常必须将数据分解为多个包,在目的地再重新组合。有可能一包或多个包在传输中丢失或遭到破坏。由于网络视频会议的实时性要求,不可能让视频传输的每一贞都准确无误。而TCP协议正是为数据可靠传输而设计的。那么选择UDP协议,即用户数据报协议(User Datagram Protocol,UDP),就成为一种必然。 Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以较为方便的编写网络上数据的传递。在Java中,有专门的Socket类来处理用户的请求和响应。利用Socket类的方法,就可以实现两台计算机之间的通讯。在JavaSocket可以理解为客户端或者服务器端的一个特殊的对象,这个对象有两个关键的方法,一个是getInputStream方法,另一个是getOutputStream方法。getInputStream方法可以得到一个输入流,客户端Socket对象上的getInputStream方法得到的输入流其实就是从服务器端发回的数据流。GetOutputStream方法得到一个输出流,客户端Socket对象上的getOutputStream方法返回的输出流就是将要发送到服务器端的数据流,(其实是一个缓冲区,暂时存储将要发送过去的数据)。 多播通信是一类特殊的IP地址(D类IP地址)这些IP地址并不和任何主机关联,而是专门为多播通信保留下来的,地址
课程设计报告 设计名称: 面向对象课程设计 选题名称: 局域网聊天程序的设计与实现 姓 名: 学 号: 专业班级: 系 (院): 设计时间: 设计地点: "指导教师评语: " " " " " " " " " " " " " " " " " " " "签名: " "年 月 日 " "1.课程设计目的 " "《面向对象程序设计》是一门实践性很强的计算机专业基础课程,课程设计是学习完该 " "课程后进行的一次较全面的综合练习。其目的在于通过实践加深学生对面向对象程序 " "设计的理论、方法和基础知识的理解,掌握使用Java语言进行面向对象设计的基本方 " "法,提高运用面向对象知识分析实际问题、解决实际问题的能力。 " "2.课程设计任务与要求: " " " "选题:局域网聊天程序的设计与实现 " " " "该程序实现局域网内的聊天功能,包括服务器端程序和客户端程序两部分。 " "客户端程序:可连接到服务器,并将消息发送到服务器端和接受服务器端发送来的信 " "息。 " "课程设计可选用NetBeans、Eclipse、JBuilder等作为开发平台以提高开发效率,尽可" "能熟练掌握其中一种集成开发环境。建议采用UML建模技术进行系统的分析设计,在Vi" "sio中画出系统用例图和类图,并将UML图复制到设计报告中。 " "通过这次设计,要求掌握以下内容: " "面向对象技术中的继承与多态(重载和覆盖)机制、各种修饰符的使用 " "类、包、接的定义与使用 " "常用工具类与算法的实现(数组、向量、字符串、链表) " "Java常用标准GUI组件及其事件处理 " "Java的异常处理机制 " " " " " " " " " " " "3.课程设计说明书 " "(1).需求分析: " "该程序实现局域网内的聊天功能,包括服务器端程序和客户端程序两部分。 " "客户端程序:包括登陆界面和聊天界面,可连接到服务器,并将消息发送到服务器端 " "和接受服务器端发送来的信息。 " "服务器端程序:负责发送用户列表和转发客户端发送来的信息 " " " "功能如下: " "连接:登陆界面输入完整之后将用户的信息发送到服务器端,服务器端创建相应的连 " "接,并将更新后的用户列表发送给所有用户。 " "刷新列表:使客户端发送一段指令到服务器端,然后由服务器端广播新的用户列表到 " "所有的客户端。 " "发送:根据发送者、发送对象、发送的话创建一个字段发送到服务器端 " "接收:根据从服务器端接收到的信息判断发送者、接受者、以及要听的话,选择显示 " "在公共聊天区还是私人聊天区。 " "颜色:设置字体颜色。 " "字体:设置字体,在楷体和宋体之间切换。 " "主题:设置背景图片。 " "快捷键:设置是否开启shift+enter发送快捷键。 " " " " " "(2).概要设计: " "本程序根据功能设置了两个界面:登陆界面以及聊天界面。 " "服务器端后台运行监听,没有设置界面。 " " " " " " " "用例图如下: " " " " " "本程序可以有多个用户,只需在一台服务器上运行服务端程序,所有的用户连接上了 " "之后就可以正常通信。 " " " " " "(3).详细设计: " "类图如下: " " " " " "本程序共有四个类,在三个源程序里。 " "In和out是客户端和服务器端通信的关键。 " "把发送功能写在了发送按钮的事件响应代码中;由于接收是要保持监听状态的,所以 " "把接收功能写在了一个进程中。 " "快捷键即键盘监听功能写在输入文本框中以实现输入完信息后按shift+enter就能等同" "点击了发送按钮。 " "改变颜色功能通过调用系统的showDialog。 " " " " " " " "4.课程设计成果 " "(1).主要代码: " "登陆界面连接服务器: " "public void link() throws Exception{ //连接服务器 核心代码 " " " "hostName = jTextField2.getText().trim(); //主机地址 " "port = Integer.parseInt(jTextField3.getText()); //端号,默认是4331,参考 " "教科书 " "client = new Socket(hostName,port); //主机地址和端号组成套接字 " " " "in = new BufferedReader(new InputStreamReader(client.getInputStream())); " "//从服务器接收到的 参考,不是很懂 " "out = new PrintWriter(client.getOutp

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值