用java多线程实现服务器与客户端之间的文件传输的代码!!!急!!!!

用java多线程实现服务器与客户端之间的文件传输的代码!!!急!!!!,第1张

程序分Server和Client
服务器端打开侦听的端口,一有客户端连接就创建两个新的线程来负责这个连接
一个负责客户端发送的信息(ClientMsgCollectThread 类),
另一个负责通过该Socket发送数据(ServerMsgSendThread )
Serverjava代码如下:
/
创建日期 2009-3-7

TODO 要更改此生成的文件的模板,请转至
窗口 - 首选项 - Java - 代码样式 - 代码模板
/
package faueMutiUser;
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintWriter;
import javanetServerSocket;
import javanetSocket;
/
服务器端

@author Faue
/
public class Server extends ServerSocket {
private static final int SERVER_PORT = 10000;
/
构造方法,用于实现连接的监听

@throws IOException
/
public Server() throws IOException {
super(SERVER_PORT);
try {
while (true) {
Socket socket = superaccept();
new Thread(new ClientMsgCollectThread(socket), "getAndShow"
+ socketgetPort())start();
new Thread(new ServerMsgSendThread(socket), "send"
+ socketgetPort())start();
}
} catch (IOException e) {
eprintStackTrace();
}
}
public static void main(String[] args) throws IOException {
new Server();
}
/
该类用于创建接收客户端发来的信息并显示的线程

@author Faue
@version 100
/
class ClientMsgCollectThread implements Runnable {
private Socket client;
private BufferedReader in;
private StringBuffer inputStringBuffer = new StringBuffer("Hello");
/
得到Socket的输入流

@param s
@throws IOException
/
public ClientMsgCollectThread(Socket s) throws IOException {
client = s;
in = new BufferedReader(new InputStreamReader(client
getInputStream(), "GBK"));
}
public void run() {
try {
while (!clientisClosed()) {
inputStringBufferdelete(0, inputStringBufferlength());
inputStringBufferappend(inreadLine());
Systemoutprintln(getMsg(inputStringBuffertoString()));
}
} catch (IOException e) {
//eprintStackTrace();
Systemoutprintln(clienttoString() + " is closed!");
}
}
/
构造显示的字符串

@param line
@return
/
private String getMsg(String line) {
return clienttoString() + " says:" + line;
}
}
/
该类用于创建发送数据的线程

@author Faue
@version 100
/
class ServerMsgSendThread implements Runnable {
private Socket client;
private PrintWriter out;
private BufferedReader keyboardInput;
private StringBuffer outputStringBuffer = new StringBuffer("Hello");
/
得到键盘的输入流

@param s
@throws IOException
/
public ServerMsgSendThread(Socket s) throws IOException {
client = s;
out = new PrintWriter(clientgetOutputStream(), true);
keyboardInput = new BufferedReader(new InputStreamReader(Systemin));
}
public void run() {
try {
while (!clientisClosed()) {
outputStringBufferdelete(0, outputStringBufferlength());
outputStringBufferappend(keyboardInputreadLine());
outprintln(outputStringBuffertoString());
}
} catch (IOException e) {
//eprintStackTrace();
Systemoutprintln(clienttoString() + " is closed!");
}
}
}
}
客户端:
实现基于IP地址的连接,连接后也创建两个线程来实现信息的发送和接收
/
创建日期 2009-3-7

/
package faueMutiUser;
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintWriter;
import javanetSocket;
/
客户端

@author Faue
/
public class Client {
private Socket mySocket;
/
创建线程的构造方法

@param IP
@throws IOException
/
public Client(String IP) throws IOException {
try {
mySocket = new Socket(IP, 10000);
new Thread(new ServerMsgCollectThread(mySocket), "getAndShow"
+ mySocketgetPort())start();
new Thread(new ClientMsgSendThread(mySocket), "send"
+ mySocketgetPort())start();
} catch (IOException e) {
//eprintStackTrace();
Systemoutprintln("ServerIP:" + IP
+ " port:10000 can not be Connected");
}
}
public static void main(String[] args) throws IOException {
try {
new Client(args[0]);
} catch (Exception e) {
Systemoutprintln("输入的IP地址错误");
}
}
/
该类用于创建接收服务端发来的信息并显示的线程

@author Faue
@version 100
/
class ServerMsgCollectThread implements Runnable {
private Socket client;
private BufferedReader in;
private StringBuffer inputStringBuffer = new StringBuffer("Hello");
/
得到Socket的输入流

@param s
@throws IOException
/
public ServerMsgCollectThread(Socket s) throws IOException {
client = s;
in = new BufferedReader(new InputStreamReader(client
getInputStream(), "GBK"));
}
public void run() {
try {
while (!clientisClosed()) {
inputStringBufferdelete(0, inputStringBufferlength());
inputStringBufferappend(inreadLine());
Systemoutprintln(getMsg(inputStringBuffertoString()));
}
} catch (IOException e) {
//eprintStackTrace();
Systemoutprintln(clienttoString() + " is closed!");
Systemexit(0);
}
}
/
构造输入字符串

@param line
@return
/
private String getMsg(String line) {
return clienttoString() + " says:" + line;
}
}
/
该类用于创建发送数据的线程

@author Faue
@version 100
/
class ClientMsgSendThread implements Runnable {
private Socket client;
private PrintWriter out;
private BufferedReader keyboardInput;
private StringBuffer outputStringBuffer = new StringBuffer("Hello");
/
得到键盘的输入流

@param s
@throws IOException
/
public ClientMsgSendThread(Socket s) throws IOException {
client = s;
out = new PrintWriter(clientgetOutputStream(), true);
keyboardInput = new BufferedReader(new InputStreamReader(Systemin));
}
public void run() {
try {
while (!clientisClosed()) {
outputStringBufferdelete(0, outputStringBufferlength());
outputStringBufferappend(keyboardInputreadLine());
outprintln(outputStringBuffertoString());
}
outprintln("--- See you, bye! ---");
} catch (IOException e) {
//eprintStackTrace();
Systemoutprintln(clienttoString() + " is closed!");
Systemexit(0);
}
}
}
}
如果对您有帮助,请记得采纳为满意答案,谢谢!祝您生活愉快!
vaela

aspnet页面通常只能使用流行的浏览器支持的技术,扩展的客户端开发技术不在aspnet范围内。
假设你使用aspnet开发一个webService或者WCF服务,它的api可以这样设计(以WCF为例):
[ServiceContract]
public interface IFileService
{
[OperationContract]
void Upload(string fileName, long position, byte[] data);
}
这表示对文件fileName,从随机存取位置position开始写入data。客户端的应用程序(但是不是aspnet,因为aspnet只是一个服务器程序,客户端还是浏览器、脚本而不是aspnet在 *** 作的)可以读取本地文件,然后(例如)按照每10k字节作为一个块去顺序或者多线程调用服务,分块的好处在于如果通讯中断则可以断点续传。

我以前写过类似的socket通信,虽然你用的方法和我的不太一样,但我还是感觉有一些问题
接受消息的时候,你用的是while(true)循环,当第一次将消息接受后,缓冲区就为空了,我想你再用循环去接收应该会出问题。
我记得有个poll方法,具体什么用途忘记了(很久没写代码了)你在循环里面加个if (clientsocketPoll(1000, SelectModeSelectRead))判断语句“clientsocket为你需要接收消息的socket”看看能不能解决,或者就用异步也可以,我可以发一下我以前的代码你参考下:
using System;
using SystemCollectionsGeneric;
using SystemComponentModel;
using SystemData;
using SystemDrawing;
using SystemText;
using SystemWindowsForms;
using SystemNet;
using SystemNetSockets;
using SystemThreading;
namespace test4_2
{
public partial class Form1 : Form
{
Socket connectSocket;
//Socket client;
byte[] bytes = new byte[1024];
delegate void listboxDel(string s);
listboxDel listboxdel;
public Form1()
{
InitializeComponent();
textBoxContentFocus();
listboxdel = new listboxDel(listbox);
//为连接指派线程
Thread threadConnect = new Thread(new ThreadStart(Connect));
threadConnectStart();

}
public void listbox(string str)
{
listBox1ItemsAdd(str);
listBox1SelectedIndex = listBox1ItemsCount - 1;
listBox1ClearSelected();
}
//连接方法
public void Connect()
{
try
{
//建立连接socket
connectSocket = new Socket(AddressFamilyInterNetwork,SocketTypeStream,ProtocolTypeTcp);
//开始异步连接
connectSocketBeginConnect(IPAddressParse("1721694152"),
82,
new AsyncCallback(ConnectCallback), //定义回调函数代理
connectSocket); //传递给回调函数的状态
}
catch (Exception e)
{
MessageBoxShow(eMessage);
}
}
//连接方法的回调函数
private void ConnectCallback(IAsyncResult ar)
{
try
{
//从传递的状态中获取套接字,创建一个客户端套接字
Socket client = (Socket)arAsyncState;
//完成挂起的连接 *** 作
clientEndConnect(ar);
listBox1Invoke(listboxdel, "连接服务器成功,可以开始通话!");
clientBeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client);
}
catch (Exception e)
{
ConsoleWriteLine(eToString());
}
}
public void receivecallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)arAsyncState;
int length = clientEndReceive(ar);
listBox1Invoke(listboxdel, EncodingUTF8GetString(bytes, 0, length));
clientBeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client);
}
catch
{
}
}
//发送方法
private void Send(String data)
{
//使用ASCII转换字符串为字节序列
byte[] byteData = EncodingUTF8GetBytes(data); //将字符串转换成字节序列
//开始向远端设备发送数据
connectSocketBeginSend(byteData, 0, byteDataLength, SocketFlagsNone,
new AsyncCallback(SendCallback), connectSocket);
}
//发送方法的回调函数
private void SendCallback(IAsyncResult ar)
{
try
{
//从传递的状态中获取套接字,创建一个客户端套接字
Socket client = (Socket)arAsyncState;
//结束异步数据传输 *** 作,返回传输的字节数
int bytesSent = clientEndSend(ar);
listBox1Invoke(listboxdel, textBoxUserText +":"+ textBoxContentText);

}
catch (Exception e)
{
MessageBoxShow(eToString());
}
}
private void buttonSend_Click(object sender, EventArgs e)
{
Send(textBoxUserText+":"+textBoxContentText);

}
}
}

NET平台很棒。真的很棒。直到它不再那么棒。我为什么不再用NET?简单来说,它限制了我们选择的能力(对我来说很重要),转移了我们的注意力,使得我们向内认知它的安全性,替代了帮助我们认知外面广阔世界的所有可能性。[系好安全带:这个文章的长度几乎成了一本书…]优点首先让我开始说说NET做得对的许多事吧,尽管这其中的大多数并不来自NET本身,但却是由NET社区而来。C#C#令人惊叹。我认为它是一个令人惊叹的编程语言。从强大的C语言背景而来,我彻底地喜欢其语法,流和这门语言的所带来的感觉。当然有我可能改变的事,但总体来说它是一门扎实的语言。并且基于开发人员使用的编程语言如此巨额的百分比和Windows *** 作系统的优越性,它是一门众所周知的语言。ReSharper我也很喜欢Resharper。在JetBrains工作的开发者们都是奇迹般的人。如果没有ReSharper和一些相关的工具,我可能并不会如此喜欢C#。BDDandMSpec我也很喜欢简称为机器规格(mspec)的BDD风格的框架。它是一个令人惊叹的测试框架,真正支持在测试中使用正确的语言测试本身。在使用mspec之前,我的测试真是一团糟并且很碍我的事。另外,当我们创建GoConvey—基于Golang的BDD测试框架的时候,Mspec对于我的组织来说是一个巨大的灵感和激励。多语言运行时我认为多语言的CLR(公共语言运行时)的观念真得使得JVM的世界思考着。我不知道任何非Java的JVM语言在CLR之前,但随着“公共语言运行时”的到来,我的理解是这使得使用JVM的人们向前进并且最终创造了如Scala和Clojure这样伟大的JVM编程语言。如果我错了请纠正我。再者,CLR使得Sun公司的人们坐下来并关注它,因为Java有一点陈旧并且随着Java8的到来,仅仅现在才在多个方面追赶着。竞争是一件非常好的事。NuGet另一个显著的例子是NuGet。这个包在Windows中作为一个整体特别是在Windows的开发中,它的管理轶事是糟透的。NuGet解决了很多问题,他们也通过从Python和Ruby借用了很多东西去做了很多正确的事。有改进的余地吗?当然。但比起其他一些选择在这儿或那儿的包升级来说,我还没有感到使用NuGet有这许多痛楚。Mono对于Mono的开发者们,我不能不说太棒了。他们所创造的太惊奇了。没有任何官方支持和不顾潜在的悬在他们头上的法律问题,他们向前推进并创造了一个居然能替代官方运行时的实现。我已经有一些运行在产品中应用程序,在Mono下运行了几乎一年而没有任何问题。它的产品准备好了吗?这可能取决于你的应用程序(见下文“Mono”)。CQRS和事件溯源可以认为,关于NET最好事之一是,它是CQRS的诞生地并有相关的技术:事件溯源。就算这样,CQRS+ES本身并没有什么很新的东西。正如GregYoung将会告诉你的,这是由一堆40年历史原料为我们重新打包并更名的。对于大型代码库我有些非常严重的问题,当我5年前使用CQRS+ES的时候,它完全释放了我的域。CQRS+ES现在是命名模式的并且其成长是显而易见的。这可能是因为NET已经能够和其他的开发平台交互共享的原因。除了这个之外,大多数的创新是从外部来的。缺点优点先放在一边,让我们看看什么出错了和我为什么不再用NET框架。关于我最近开发平台的迁移,最能激励我的事是我可以利用许多最好的部分而丢下不好的部分(如下文所说)。Windows正如前文所述,当面对基于网络的服务器软件时,Windows并不是一个好的选手。在我看来,Windows的另一个真正的大问题是传统的Windows开发者是通常仅仅擅长于Windows,当他们离开安乐窝之后就会很快迷失,这对于Linux开发者来说却不是问题。计算远不止是Windows。开发者仅仅能 *** 作单一的 *** 作系统的一个问题是它不可避免得导致Windows的激增。换句话说,Windows生了Windows。没法打破这个循环。另一方面,NIX的开发者通常熟悉多 *** 作系统(Linux,Unix,OSX,Windows等等),一个 *** 作系统的内部工作原理,不同的分布(基于Debian和基于Fedora),窗口管理器,桌面管理器,文件系统,包管理,编译,重新编译,重新打包,命令行“fu”等等。我的一个心病是文件系统。NTFS并不是系统唯一的文件系统,对于任何给予的任务它几乎都不是最好的选择。ZFS,BTRFS,ReiserFs,ext等等,有一些很酷的特性。我也很喜欢为了各种高速/透明的磁盘 *** 作,能从BASH创建回路设备或者创建RAM设备。这在Windows中不会发生—如果没有第三方软件的话。在AWS云服务中,启动一个Windows机器要花掉足足10多分钟。我大约15-20秒就能启动一个简单的Linux机器。当涉及到云计算规模,它能够迅速扩展是很重要的,因为当扩展很重要时,10-15分钟就像是永恒的。VisualStudio在我这另一根刺,当属VisualStudio。我需要一个大大超出预期的IDE去做任何开发,这个想法困扰着我。它只是如Windows一样庞大的资源猪。我有一个内核i73770K35GHZ的台式机,以16GB的内存和最大4512GB的固态硬盘去编译。它差不多刷爆了Windows体验指数,但Windows+VS仍然很慢。(是的,ReSharper使得它更慢了,但是ReSharper对这来说是值得的。)现在我在MacBookPro上开发,它比起我的强大的台式机来说只有更少的CPU马力,但运行明显更快,在一个短小的学习曲线之后,UX(用户体验)变得无限美好了。事实上,我甚至不再用鼠标了—我的双手一直在键盘或触控板上,我可以用手势 *** 作我的电脑并让它回应—不像在Windows。关于VS很酷的一个事是调试器。它的查看和使用,令人难以置信得方便。每隔一段时间会在监视窗口报告错误的值,导致花费时间去调试。同时,这也是很大的负面,因为CLR默认的,多线程的世界使得我一开始就需要一个调试器。没有调试器是一个解脱的体验,因为它迫使你以另一种方式编程。VS同样也有创建“csproj”和“sln”文件的坏毛病。我恨这些。当然,C#必须知道编译什么和何时编译。我理解这点。在Golang中,引用在代码中使用了很重要的语句。如果它不是NET中用到的工程文件,我可能使用简单的文本编辑器编码C#,并且对这门语言更流畅。使用gitrebase *** 作时,这些文件也有导致合并冲突。别让我开始说换行符的差异。我不能相信直到今天我们还在处理这样的事。如果VS解决方案文件以Linux行结束符结束,通过双击它并不能载入该解决方案,因为VS解决方案文件分析器读不出它来。源代码管理幸运的是,我早就跳出了微软阵营的源代码管理(版本控制系统VSS)。我早在2000年初,在VSS无数次丢失了我的提交之后,就使用了Subversion(译者注:Subversion是开源的版本控制系统)。之后git(译者注:git是开源的版本控制系统,内容管理系统等)出现了,我又迷上了它。不幸的是,没有Windows的接口—对我来说是典型的遭遇。最终有人创建了一个接口,我就用了那个并且没有回头。Git是一把非常锋利的刀,但当你正确运用它的时候,它是一个强大而高效的工具。我曾经在一个小工程中用过TFS(译者注:TeamFoundationServer,工作流协作引擎),它是一个怪物—和所有来自Redmond(译者注:美国微软总部)的产品一样。它感染了我的项目文件并且污染了我的源代码目录。真可恶。不,还是谢谢你。给了我任意一天用命令行git…或者可能是SourceTree,如果你需要从GUI得到一点关爱。Mono是的,这是第二次提及Mono。正如Mono本身如此惊艳一样。在NET的世界,它仍然二等公民。无论什么时候我尝试在Mono上运行任何重要的东西,我通常都在和漏洞作斗争。幸运的是,对下载代码,查找问题,发送请求和在Linux上编译代码我没有感到不舒服。但是这件事我都记不清做了多少遍了。是的,CLR是个巨大的怪物,并且对一个非官方的应用在不同的 *** 作系统都有相同的行为,简直是个类似于分开红海的奇迹。但事实是,我不得不花费如此多的时间来填补漏洞以使我的代码能够正确运行,实在是很难为其辩护。Mono的特定区域也慢。也许它不是在慢在过载,但对我来说Web服务器是关键所在。并且它非常慢,最后,慢到了最底下—即使是微不足道的东西。我想好消息是它只能从这儿得到更好的。我也应该提及Mono的开发者可能忘了Linux,比起我可能知道的还多,所以我不能太挑剔。IIS也许IIS在尝试着为太多的应用程序做太多的事情。它从作为一个web服务器变为像J2EE应用程序容器一样的应用程序宿主。它也站在慢速这一边。我猜如果我需要更高的性能,我应该编写我自己的web服务器,但我真的很想只关注我应用程序的代码。可能利用Windows事件服务器将是好的,但nginx(译者注:一个高性能的>某宝至强e5处理器好的有Intel Xeon E5-1603,Intel Xeon E5-2600。具体如下:

(1)Intel Xeon E5-1603

Intel Xeon E5-1603是一款性能很稳定的服务器CPU,能够积极响应服务请求并进行处理,处理能力、稳定性、可靠性、安全性、可扩展性、可管理性等方面的能力都有保障。

(2)Intel Xeon E5-2600

Intel Xeon E5-2600是一款稳定、低频率、低功耗,多核心,多线程的服务器CPU。E5来说优点就是高频率、超频。

扩展资料:

CPU控制技术的主要形式

(1)选择控制。集中处理模式的 *** 作,是建立在具体程序指令的基础上实施,以此满足计算机使用者的需求,CPU 在 *** 作过程中可以根据实际情况进行选择,满足用户的数据流程需求。 指令控制技术发挥的重要作用。

根据用户的需求来拟定运算方式,使数据指令动作的有序制定得到良好维持。CPU在执行当中,程序各指令的实施是按照顺利完成,只有使其遵循一定顺序,才能保证计算机使用效果。

CPU 主要是展开数据集自动化处理,其 是实现集中控制的关键,其核心就是指令控制 *** 作。

(2)插入控制。CPU 对于 *** 作控制信号的产生,主要是通过指令的功能来实现的,通过将指令发给相应部件,达到控制这些部件的目的。

实现一条指令功能,主要是通过计算机中的部件执行一序列的 *** 作来完成。较多的小控制元件是构建集中处理模式的关键,目的是为了更好的完成CPU数据处理 *** 作。

(3)时间控制。将时间定时应用于各种 *** 作中,就是所谓的时间控制。在执行某一指令时,应当在规定的时间内完成,CPU的指令是从高速缓冲存储器或存储器中取出,之后再进行指令译码 *** 作,主要是在指令寄存器中实施,在这个过程中,需要注意严格控制程序时间。

多线程请求并发这个服务器已经做好了(比如tomcat),你不需要考虑,action的处理看你要用的是哪个框架了,如果是struts2 不用考虑多线程,如果是原始的servlet必须考虑并发的临界资源问题。
如果你是想自己实现一个容器,咱们在令当讨论


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/13260927.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-06-28
下一篇 2023-06-28

发表评论

登录后才能评论

评论列表(0条)

保存