저는 간단한 c 서버와 Java 클라이언트 구현이 있으며 요청 처리를 위해 서버를 테스트하고 있습니다. 동시 요청을 시뮬레이트하기 위해 실행 프로그램 서비스를 사용하고 있습니다.Java 클라이언트에서 실행자 서비스를 사용하는 동안 c 서버에서 데이터를받지 못했습니다.
메커니즘 : 서버는 클라이언트에서 문자열을 읽고 클라이언트에 메시지를 보내이를 인식합니다.
문제 : 일부 요청의 경우 서버는 클라이언트가 보낸 메시지를받지 못합니다.
C 서버 :
#include <stdio.h>
#include <string.h> //strlen
#include <stdlib.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <unistd.h> //write
#include <pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c;
struct sockaddr_in server , client;
static int client_count = 0;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(5000);
//Bind
if(bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 1000);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
pthread_t thread_id;
while((client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)))
{
client_count++;
printf("Connection accepted for client no : %d\n",client_count);
if(pthread_create(&thread_id , NULL , connection_handler , (void*) &client_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join(thread_id , NULL);
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size, t = 0, operation = -1, buffer_size = 0;
char *message , recv_meta[2000], *data[3];
//Receive a message from client
while(read_size = recv(sock, recv_meta, 2000, 0) > 0) {
printf("Meta from client : %s\n",recv_meta);
sprintf(recv_meta, "%s", "OK, Meta Data received!");
send(sock, recv_meta, strlen(recv_meta), 0); //send acknowledgement
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
자바 클라이언트 :
import java.net.*;
import java.io.*;
import java.util.Arrays;
import java.util.concurrent.*;
public class client
{
public static void main(String[] args)
{
ExecutorService executorService = Executors.newFixedThreadPool(100);
for (int i = 0; i < 5; i++) {
Runnable worker = new WorkerThread(""+i);
executorService.execute(worker);
}
executorService.shutdown();
}
}
class WorkerThread implements Runnable {
String clientcount = "";
public WorkerThread(String s){
this. clientcount=s;
}
@Override
public void run() {
Socket socket = null;
int PORT = 5000, buffer_size = 0;
String meta = " ";
meta = "newfileidforenc:1:20000";
// Create the socket connection to the EchoServer.
try
{
socket = new Socket("localhost", PORT);
}
catch(UnknownHostException uhe)
{
// Host unreachable
System.out.println("Unknown Host");
}
catch(IOException ioe)
{
// Cannot connect to port on given host
System.out.println("Cant connect to server at port "+PORT+". Make sure it is running.");
return;
}
try
{
PrintWriter pout = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader pin = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pout.println(meta);
pout.flush();
System.out.println("\nServer Says : " + pin.readLine() + "for "+ clientcount);
}
catch(Exception ioe)
{
System.out.println("\nException during communication. Server probably closed connection.");
}
finally
{
try
{
// Close the socket before quitting
socket.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
출력 : 그것은 동일하지 않습니다. 모든 클라이언트가 연결되고 성공적으로 연결이 끊어집니다. 그러나 서버는 모든 클라이언트의 데이터를 수신 및 인쇄하지 않습니다.
글쎄, 곧바로, 서버는 읽기 성공 후 recv() 호출에서 'read_size'리턴을 무시합니다. 그런 다음 'printf ("클라이언트의 메타 : % s \ n", recv_meta);' null로 끝나는 것이 보증되어 있지 않은 버퍼를 printf하려고 시도한다. –
recv() 호출이 한 번에 클라이언트에서 보낸 전체 줄을 읽는 경우 (보장되지 않음)에도 클라이언트는 null로 종료되지 않는 데이터를 보냅니다. –
'pthread_create (...., client_sock')는 값으로 전달하는 대신 accept() 스레드에 로컬 인 var의 주소를 전달합니다. –