java 编写的服务器客户端socket无法持续收发信息

java 编写的服务器客户端socket无法持续收发信息,第1张

  

serverSocket = new ServerSocket ( 9999 );

serverThread = new ServerThread ( serverSocket );

serverThreadstart ( );

看你这块的代码,你的server定义了serverSocket,当你开启服务后,新建了一个服务线程,去监听

while( flag ){

try{

    Socket socket = serverSocketaccept( );

    ServerThreadAgent serverThreadAgent = new ServerThreadAgent( socket );

    serverThreadAgentstart( );

}

catch( Exception e ){

    eprintStackTrace( );

}

在监听的线程中,当遇到客户端的请求时,创建一个Socket,与客户端建立一条通道,进行通信

public void run ( )

{

    try

    { 

    

        Object message = SocketUtilreadStream ( socket );// 接收信息

        Systemoutprintln ( socketgetInetAddress ( ) + "发来信息:"

        + message);

        String sendMessage = "信息已经收到。";

        SocketUtilwriteStream ( sendMessage, socket );// 发送信息

    }

    catch ( Exception e )

    {

        eprintStackTrace ( );

    }

}

看你的与客户端保持连接的服务代理,服务代理线程开启后,先是接受客户端的信息,先是出来,然后向客户端发送一条消息,然后,然后呢???????

然后,就没有然后来了,服务代理线程的生命就此结束,也就是说客户端与服务端的通话结束,连接已经断开。

与客户端既然已经断了,怎么可能进行消息传递呢???

这样一分析,问题明显出来了,问题出在哪?

问题就是在于与客户端保持通话的服务代理线程,怎样才能保持通话呢?

那就是在代理线程的run方法中进行循环进行监听,也就是说消息的接受,这样,才能保持通话,想结束的时候,就退出循环,或是客户端主动的结束通话。

我大致看了下代码,没有什么问题,你需要注意其他的地方:

服务器地址是否填写正确,有没有弄错,请在发送Socket请求之前Ping一下试试,如果通则代码可以正常访问,若不通,则地址一定有问题。

检查端口号是否有问题,服务器端口号有没有填写错误。

槛车服务器网络防火墙是否开启,默认开启状态下,你怎么的也是请求不进去的。

服务器服务是否正常开启,他不开启你怎么的也请求不进去。

TCP协议通信,接收方接收数据的前后次序与发送方一致,但数据包不一定一致。打个比方,发送方按顺序发送了2个数据包,接收可能仅接收1次就能全部收到,也可能需要收2次才能收到,也可能收3次,每次收到的数据大小不一定和发送方发送的数据包大小一样,但最终收到的总数据是一致的。

从你的程序来看,客户端连续发送2包数据,服务器端有可能一次就全部接到,也可能分2次收到,也可能会收2次以上才能收到。如果在发送“########helloworld”和“######whatisit”之间增加一些延时语句,比如延时1秒,那么可以肯定服务器端只能收到1次,因为在发送第1包数据的时候,服务器端就接收到一次数据,而在发送第2包数据时,服务器已经不再有接收动作了。

就现在的客户端程序来说,如果要在服务器端收到所有数据,可以考虑在服务器端循环接收数据,拼装数据,直到收不到数据为止,然后输出所有接收到的数据。

while(1)

{

int rr;

sock_fd = accept( sock, NULL, NULL);

retval = 0;

while(1)

{

rr = recv( sock_fd, buf1, MAX_BUFLEN, 0 );

if(rr==0) break;

memcpy(buf+retval,buf1,rr);

retval+=rr;

}

printf("buf= %s\n ##retval=%d\n",buf,retval);

write(sock_fd,"get the call\n",sizeof("get the call\n")-1);

}

可以试试看。仅供参考。

查到个函数ioctlsocket

while(1)

{ int rr;

sock_fd = accept( sock, NULL, NULL);

retval = 0;

int iMode = 1; //0:阻塞

ioctlsocket(sock_fd,FIONBIO, (u_long FAR) &iMode);//非阻塞设置

while(1) { }

}

服务端监听socket正常是不与任何客户端socket进行通信的。监听socket死循环作监听工作,当收到一个连接之后,创建一个新的socket来与客户端通信。这样理论上一个服务端可以与上万的客户端通信。只是要记住,每个真正参与通信的socket都需要开两个单独的线程来进行消息的收发。

如题,我写了段Socket服务器\客户端通讯的程序,服务端能接收到客户端的数据,但是客户端就无法接收到服务端传回的数据,代码如下Server端import javaioBufferedReader; import javaioIOException; import javaioInputStreamReader; import javaioPrintWriter; import javanetServerSocket; import javanetSocket; / @author Think / public class SocketServer { / @param args / public static void main(String[] args) { new SocketServer()start(); } public void start(){ try { ServerSocket server = new ServerSocket(10086); while(true){ Systemoutprintln("Waiting for a client"); Socket client = serveraccept(); new SocketServerThread(client)start(); } } catch (IOException e) { eprintStackTrace(); } } class SocketServerThread extends Thread{ Socket client = null; public SocketServerThread(Socket client){ thisclient = client; } @Override public void run(){ try { // 得到CLIENT的输入流,从输入流出取出传输的数据 BufferedReader reader_from_client = new BufferedReader(new InputStreamReader(clientgetInputStream())); String line = null; Systemoutprint("from client message:"); while((line = reader_from_clientreadLine()) != null){ Systemoutprintln(line); } // 得到CLIENT端的输入流,通过向CLIENT传输数据 PrintWriter writer_to_client = new PrintWriter(clientgetOutputStream()); writer_to_clientprintln("Ok"); writer_to_clientflush(); reader_from_clientclose(); writer_to_clientclose(); clientclose(); } catch (IOException e) { } } } } Client

import javaioBufferedReader; import javaioIOException; import javaioInputStreamReader; import javaioPrintWriter; import javanetInetAddress; import javanetSocket; / @author Think / public class SocketClient { / @param args / public static void main(String[] args) { try { Socket remoteServer = new Socket(InetAddressgetLocalHost(), 10086); // 得到SERVER端SOCKET的输出流,通过向输出流写入数据,与SERVER进行通信 PrintWriter write_to_server = new PrintWriter(remoteServergetOutputStream(), true); write_to_serverwrite("Hello, what's you name"); write_to_serverflush(); // 把下面这几行放开,SERVER端就收不到数据了,一直处于阻塞状态 // 得到SERVER端的输出流,从输出流中读取从SERVER传递来的数据 // BufferedReader reader_from_server = new BufferedReader(new InputStreamReader(remoteServergetInputStream())); // String line = null; // while((line = reader_from_serverreadLine()) != null){ // Systemoutprintln(line); // } // reader_from_serverclose(); write_to_serverclose(); remoteServerclose(); } catch (IOException e) { eprintStackTrace(); } } }如果Client中的说明,只要是Client中放开了

BufferedReader reader_from_server = new BufferedReader(new InputStreamReader(remoteServergetInputStream())); String line = null; while((line = reader_from_serverreadLine()) != null){ Systemoutprintln(line); } reader_from_serverclose(); 这段代码,SERVER就阻塞在

while((line = reader_from_clientreadLine()) != null){ 这行,不知道是哪个环节理解或处理错了,还望大家指点指点!

即使不关闭连接,也是取不到数据,看了下其它类似的提问,问题在于readLine()会导致阻塞,还在摸索解决的办法! 问题补充:wgy_superpower 写道第一:Socket编程时,永远不要在关闭写(writer)之前关闭读(reader)

第二:不管是客户端还是服务端在通过Socket读取数据的时候,在你的数据传输完成后,发送一个结束标记(比如:end),这样在你的 while循环里面判断一下数据是否已经传输完毕,完毕后跳出循环,否则由于你的程序就会一直阻塞在 readLine()这里,因为你的 socket还没有断开,会一直等待你写数据。

你说的有道理,经过后来的试验,确实是因为readLine()一直等待着客户端的输入,但此时客户端也在等待服务端的返回,所以导致两边都在那等待,就阻塞了。

一句话就是,一直等待写数据,但又没有数据写入,所以就卡住了。 问题补充:anranran 写道SocketServer : while((line = reader_from_clientreadLine()) != null)

这个在socket没有关闭的时候是无法输出来的。

所以Server do not send any data to client嗯,也有道理,但主要不是socket没有关闭,而是没有向流中写数据,而readLine()又一直在那读取,所以就阻塞了!

1)如果“数据条数”定义是:客户端发送数据帧的数量,那么,服务器每当收到一次客户端的数据帧,计数就加1;例如,客户端A连续发送了“你好”,“我在这里”两条信息,服务器的计数就应该增加2;

2)服务器可以接收来自多个客户端的数据,可以分别统计每个客户端数据条数,也可以统计所以客户端数据总的条数。

针对上面两个需求,实现起来大致框架如下:

1)定义一个Dictionary<string, int> num,用来计数

Dictionary<string, int> num= new Dictionary<string, int>();

其中,泛型参数string用于表示客户端;int用于计数

2)每当服务器接收到来自客户端数据后,可以获得客户端的IPEndPoint clientEP,将clientEP转换成字符串,作为Dictionary 的键值,用来标识客户端

string client  = clientEPToString();

if(!numContainsKey(client))

{

    //在集合中添加一个客户端计数项

     numAdd(client, 0);  

}

//数据条数加1

num[client]++;

3)分别统计并显示每个客户的数据条件

foreach( var c in num)

{

    ConsoleWriteLine("客户端{0},总数{1}", cKey, cValue);

}

4)统计并显示服务器接收到所有客户端数据条数的总数

var qry = from c in numValues select c

ConsoleWriteLine("接收总数{0}", qrySum());

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » java 编写的服务器客户端socket无法持续收发信息

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情