C与java之间的Socket通信
我有一个客户机和一个服务器都在C中运行。我的任务是介绍java程序,在这个程序中,我为C客户机创建一个服务器,为C服务器创建一个客户机。我成功地尝试正确设置连接。然而,问题在于两个C程序之间的数据通信。下面是我在java程序中编写的内容:C与java之间的Socket通信,java,c,sockets,network-programming,communication,Java,C,Sockets,Network Programming,Communication,我有一个客户机和一个服务器都在C中运行。我的任务是介绍java程序,在这个程序中,我为C客户机创建一个服务器,为C服务器创建一个客户机。我成功地尝试正确设置连接。然而,问题在于两个C程序之间的数据通信。下面是我在java程序中编写的内容: while(true){ while((userInput1=br1.readLine())!=null||(userInput2=br2.readLine())!=null){ if(userInput1=!null){ bw1.write
while(true){
while((userInput1=br1.readLine())!=null||(userInput2=br2.readLine())!=null){
if(userInput1=!null){
bw1.write(userInput1);
bw1.flush();
}
if(userInput2=!null){
bw2.write(userInput2);
bw2.flush();
}
}
在调试上述代码时,可以看到执行被卡在第二个While语句,这意味着输入流永远在等待C客户机的输入。我正在为流使用BufferedReader和BufferedWriter。C客户机和服务器使用send和recv函数进行通信。
请帮助输入,使java程序能够帮助两个C程序彼此通信,就像它们没有这样做一样。您是否正确考虑了java的“短路”或运算符的影响 对于| |如果第一个子句为真,则第二个从句永远不会被计算
while(
(userInput1=br1.readLine())!=null ||
(userInput2=br2.readLine())!=null) {
所以你成功地阅读了
userInput1=br1.readLine())!=null
并立即输入处理,然后返回while并再次将下一行读入userInput1。因此,userInput2永远不会收到值
你需要像这样的独立逻辑
read first line
read second line
但是,当读取第2行和a行时,如果数据尚未准备好,您应该做些什么呢?再试一次?您阅读的下一行是预期的第2行还是新的第1行?这是一个相当棘手的问题
我不希望在我的协议中依赖两个独立的读线
while((userInput1=br1.readLine())!=null||(userInput2=br2.readLine())!=null){
这种情况意味着您将在从br2读取任何内容之前,一直读取br1到EOS。这是你真正想要的吗
相反,如果您被困在br2.readLine()
上,则意味着两件事:(a)br1
在EOS,以及(b)与br2
相关联的对等方没有发送任何内容,或者至少没有发送以换行结束的行
您是否有一种常见的错觉,即当没有数据可供读取时,readLine()返回null
另外,您正在读取以换行符结尾的行,这些行被readLine()调用删除,然后在没有任何换行符的情况下将它们写出,这很难是正确的
在我看来,您真正编写的是一个代理,在这种情况下,每个套接字需要两个线程,一个从a读取并写入B,另一个从B读取并写入a。如果是代理,您应该使用InputStreams和OutputStreams,而不是读卡器和写卡器,因为您可能没有理由检查数据,因此,您不应该通过使用读卡器和写卡器所隐含的字节->字符和字符->字节转换过程来处理它。在编写代理时还有更多的微妙之处,但我将在解释它们之前等待您的确认。我使用奇偶校验字符的原因是为了解释流的结尾。否则,仅使用read()将使程序永久停止输入(即使在实际程序发送了其所有数据之后)。我使用ready()的方式如下:
//The proxy client
while(true){
if(br1.ready()){
while((temp1=br1.read())!=(int)par)
userInput1=userInput1+(char)temp1;
System.out.println("Input to Actual Server: " + userInput1);
bw1.write(userInput1);
bw1.flush();
System.out.flush();
userInput1="";
temp1=0;
}
if(br2.ready()){
while((temp2=br2.read())!=(int)par)
userInput2=userInput2+(char)temp2;
System.out.println("Response from Actual Server: " + userInput2);
userInput2=userInput2+par;
bw2.write(userInput2);
bw2.flush();
System.out.flush();
userInput2="";
temp2=0;
}
}
//The proxy server
while(true){
if(br1.ready()){
while((temp1=br1.read())!=(int)par)
userInput1=userInput1+(char)temp1;
System.out.println("Input from Actual Client: " + userInput1);
userInput1=userInput1+par;
bw1.write(userInput1);
bw1.flush();
System.out.flush();
userInput1="";
temp1=0;
}
if(br2.ready()){
while((temp2=br2.read())!=(int)par)
userInput2=userInput2+(char)temp2;
System.out.println("Response to Actual Client: " + userInput2);
bw2.write(userInput2);
bw2.flush();
System.out.flush();
userInput2="";
temp2=0;
}
}
请建议使用ready()是否有任何问题。我对Java网络了解不多,但在我看来,用于读卡器的套接字正在阻塞。您需要使用非阻塞套接字。您有两个套接字连接。当第一个连接不发送数据时,是否需要第二个连接块??是否有任何原因不使用线程,以便可以独立读取套接字连接。如果两个连接之间存在依赖关系,您能说出它是什么吗?我使用了| |运算符,以确保在某个时间只有客户机或服务器准备好提供输入,而另一个等待输入或参与自己的某些操作。因此,每次while循环启动时,任何一个条件都应保持为true(输入将在客户端或服务器端给出),因此,输入应写入相应的输出流。lemme还提醒您,当执行被卡在第二个while语句时,如果我终止C客户机程序,已经给出的输入现在被写入服务器的输出流,并且服务器开始响应该输入,即,只有当客户机程序结束时,才意识到它已经到达缓冲区的末尾。有什么输入吗?所以你有混合客户端和服务器端的代码?对不起,我没意识到。按照我的口味,这不是一个干净的设计。所以你建议编写两个独立的java程序,一个作为实际C服务器的客户端,另一个作为实际C客户端的服务器。然后在此客户机和服务器之间建立连接。我很抱歉,如果我在这里显得过度使用人。我只是在学习的过程中。。请建议..是的,单独的客户端和服务器程序,或者至少单独处理客户端和服务器端的方法。我声称,通过分离关注点,您的代码将更容易理解。我现在有两个线程可以很好地完成这项工作。我使用br1.ready()和br2.ready()来了解流中是否有数据。还使用了一种技术在原始通信程序中添加奇偶校验字符,以便通过我的代理发送数据。我现在正在读取数据,直到遇到这个奇偶校验并将其发送到通信部分的另一端。这似乎很有效。是的,我仍然继续使用InputStreamReader和OutputStreamWriter。如果有更好的处理方法,请告诉我。谢谢。@abhiram不要使用ready()。你有两条线。块线程还能做什么?如果您知道数据仅为字符数据,则应仅使用读卡器和写卡器。如果现在、将来或遥远的将来它可能是二进制的,那么使用Streams:换句话说,使用Streams。我不知道当你只是在客户端和服务器之间进行中介时,为什么你需要这个奇偶校验,也就是说,你是一个代理。正义公司