2015-02-03 3 views
0

저는 간단한 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(); 
      }     
     } 
    } 
} 

출력 : 그것은 동일하지 않습니다. 모든 클라이언트가 연결되고 성공적으로 연결이 끊어집니다. 그러나 서버는 모든 클라이언트의 데이터를 수신 및 인쇄하지 않습니다.

+0

글쎄, 곧바로, 서버는 읽기 성공 후 recv() 호출에서 'read_size'리턴을 무시합니다. 그런 다음 'printf ("클라이언트의 메타 : % s \ n", recv_meta);' null로 끝나는 것이 보증되어 있지 않은 버퍼를 printf하려고 시도한다. –

+0

recv() 호출이 한 번에 클라이언트에서 보낸 전체 줄을 읽는 경우 (보장되지 않음)에도 클라이언트는 null로 종료되지 않는 데이터를 보냅니다. –

+0

'pthread_create (...., client_sock')는 값으로 전달하는 대신 accept() 스레드에 로컬 인 var의 주소를 전달합니다. –

답변

0

문제점에 대한 해결책을 찾았습니다.

실제 문제 : 실행자 서비스는 부하 테스트에 사용됩니다. 즉, 초당 더 많은 요청이 전송됩니다. 무거운 하중이 가해지면 코드가 경쟁 조건에 들어갑니다. 주소가 pthread_create()에 전달 된 client_sock은 connection_handler() 내부의 sock 변수에 복사되기 전에 다음 accept() 호출에 의해 덮어 쓰여지고 있습니다. 이것은 하나의 연결이 두 개 이상의 스레드에 의해 처리되고 다른 연결이 처리되지 않은 채로 남아있는 시나리오로 연결됩니다.

해결 방법 : client_sock을 pthread_create()에 대한 인수로 전달되어야하는 문자열 버퍼로 복사하십시오.

희망이 있으면 유용 할 것입니다.

0

당신은 수많은 문제가 :

)를 정확하게 TCP 스트림을 처리하고 TCP 대신 옥텟의 메시지를 전송한다고 가정하지 않음을, (바이트) 스트리밍합니다.

2) 문자열 유형으로 msaquerade하는 C 스타일 Null 종료 문자 배열을 인식하지 못합니다.

3) 주소를 스레드에 전달하면 전화가 걸립니다.

의견보기.

+0

도움에 감사드립니다. 문제에 대한 해결책을 찾았습니다. – Sudershan

관련 문제