【发布时间】:2018-03-17 00:21:18
【问题描述】:
我正在尝试重用相同的套接字在 C++ 客户端和 Java 服务器之间发送和接收字符串(和/或字节)(反之亦然)。从某种意义上说,我可以重用套接字,因为我可以从 Java 发送(一次)并从 C++ 接收(一次),并且反过来做同样的事情(从 C++ 发送到 Java)。但是,如果我多次尝试从 C++ 发送到 Java,第二个(字符串或字节)将不会出现。对于字符串(从 C++ 发送一个字符数组),我总是得到一个空值。请注意,在使用相同代码在 C++ 和 C++ 或 Java 和 Java 之间进行通信时,我没有这个问题。我知道 BufferedInputReader 需要一个新行。对于字节,我得到 IndexOutOfBound。请参见下面的代码。 Java服务器-->
// in main...
TCP tcp = new TCP();
tcp.sendStr("Send File");
String x = tcp.recvStr();
System.out.println(x);
x = tcp.recvStr();
System.out.println(x);
//issue starts from here
x = tcp.recvStr();
System.out.println(x);
//.... IN TCP CLASS
// Global class variables in TCP
ServerSocket serverSocket = new ServerSocket(8080);
serverSocket.accept(); // this is done somewhere in the class
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
public String recvStr(){
String msg = null;
try {
msg = br.readLine();
}
catch (Exception e) {
e.printStackTrace();
}
return msg;
}
public void sendStr (String msg) {
try {
pw.write(msg);
pw.flush();
}
catch (Exception e) {
e.printStackTrace();
}
}
C++ 客户端代码
//.. main thread of execution
struct sockaddr_in server_address, client_addr;
memset(&server_address, '0', sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(PORT);
TCP tcp;
char receiveBuffer[1024] = {};
int server_fd = 0, new_socket = 0;
tcp.RecieveChar(server_address, receiveBuffer, new_socket);
std::cout << receiveBuffer << std::endl;
char chunkSize[64] = "yeahh!\n";
tcp.SendChar(server_address, chunkSize, new_socket, server_fd);
char chunk[128] = "weeeee\n";
tcp.SendChar(server_address, chunk, new_socket, server_fd);
//... in class tcp
template<int SIZE>
void TCP::SendChar(struct sockaddr_in server_addr, const char (&data)[SIZE], int &socket_id, bool close_connection ){
int opt = 1;
int addrlen = sizeof(server_addr);
int server_accept;
// Creating socket file descriptor
// Create one if only one does not exist
if(socket_id == 0){
if ((socket_id = socket(AF_INET, SOCK_STREAM, 0)) == 0)
{
std::cerr << "Error in creating socket" << std::endl;
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 8080
if (setsockopt(socket_id, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
&opt, sizeof(opt)))
{
std::cerr << "Error in setting socket" << std::endl;
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port
if (bind(socket_id, (struct sockaddr *)&server_addr,
sizeof(server_addr))<0)
{
std::cerr << "Error in binding socket" << std::endl;
exit(EXIT_FAILURE);
}
if (listen(socket_id, 3) < 0)
{
std::cerr << "Error in accepting listening" << std::endl;
exit(EXIT_FAILURE);
}
if ((server_accept = accept(socket_id, (struct sockaddr *)&server_addr,
(socklen_t*)&addrlen))<0)
{
std::cerr << "Error in accepting connection" << std::endl;
exit(EXIT_FAILURE);
}
socket_id = server_accept;
}
sendto(socket_id, data, SIZE, 0, (struct sockaddr*) &server_addr, sizeof(server_addr)); // need to change to client address?
}
void TCP::RecieveChar(struct sockaddr_in server_addr, char *received_data,
int &socket_address_binder, bool close_connection){
int valread;
if(socket_address_binder == 0){
if ((socket_address_binder = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
std::cerr << "\n Socket creation error" << std::endl;
}
if (connect(socket_address_binder, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
std::cerr << "\nConnection Failed \n" << std::endl;
}
}
valread = read( socket_address_binder , received_data, 1024);
if(valread == 0){
std::cerr << "Error in read" << std::endl;
}
std::cout << "Received: " << received_data << std::endl;
}
请注意,我已包含用于发送和接收字符/字符串数组的代码。我也可以毫无问题地在两者之间发送文件,但是当我在 Java 中接收到字符串后尝试重用套接字时,出现以下错误:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:128)
【问题讨论】:
-
你在使用多线程吗?如果您将
sendStr设为synchronized方法,问题会消失吗? -
不使用多线程,一个线程执行
-
@VGR :看我的回答,我知道问题出在哪里,但是您仍然可以帮助理解原因。
标签: java c++ sockets bufferedreader