2012-03-03 8 views
0

私はこの例をCスレッドサーバーとJavaクライアントで処理しています。これはサーバです:Javaクライアントの接続後にCサーバーがクラッシュする

#include <stdio.h> 
#include <sys/ioctl.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <pthread.h> 

void* thread_proc(void *arg); 

int main(int argc, char *argv[]) 
{ 
    struct sockaddr_in sAddr; 
    int listensock; 
    int result; 
    int nchildren = 6; 
    pthread_t thread_id; 
    int x; 
    int val; 

    listensock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 

    val = 1; 
    result = setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); 
    if (result < 0) { 
     perror("server"); 
     return 0; 
    } 

    sAddr.sin_family = AF_INET; 
    sAddr.sin_port = htons(6000); 
    sAddr.sin_addr.s_addr = INADDR_ANY; 

    result = bind(listensock, (struct sockaddr *) &sAddr, sizeof(sAddr)); 
    if (result < 0) { 
     perror("exserver5"); 
     return 0; 
    } 

    result = listen(listensock, 5); 
    if (result < 0) { 
     perror("exserver5"); 
     return 0; 
    } 

    for (x = 0; x < nchildren; x++) { 
    result = pthread_create(&thread_id, NULL, thread_proc, (void *) listensock); 
    if (result != 0) { 
     printf("Could not create thread.\n"); 
     return 0; 
    } 
    sched_yield(); 
    } 

    pthread_join (thread_id, NULL); 
} 

void* thread_proc(void *arg) 
{ 
    int listensock, sock; 
    char buffer[25]; 
    int nread; 

    listensock = (int) arg; 

    while (1) { 
    sock = accept(listensock, NULL, NULL); 
    printf("client connected to child thread %i with pid %i.\n", pthread_self(), getpid()); 

    while(1){ 
     nread = recv(sock, buffer, 25, 0); 
     buffer[nread] = '\0'; 
     printf("%s\n", buffer); 
     send(sock, buffer, nread, 0); 
     if(nread == '9'){ 
     close(sock); 
     } 
     } 

    printf("client disconnected from child thread %i with pid %i.\n", pthread_self(), getpid()); 
    } 
} 

これは、Javaクライアントである:

import java.net.*; 
import java.io.*; 

// A client for our multithreaded EchoServer. 
public class client 
{ 
    public static void main(String[] args) 
    { 
     Socket s = null; 

     // Create the socket connection to the EchoServer. 
     try 
     { 
      s = new Socket("localhost", 6000); 
     }   
     catch(UnknownHostException uhe) 
     { 
      // Host unreachable 
      System.out.println("Unknown Host"); 
      s = null; 
     } 
     catch(IOException ioe) 
     { 
      // Cannot connect to port on given host 
      System.out.println("Cant connect to server at 6000. Make sure it is running."); 
      s = null; 
     } 

     if(s == null) 
      System.exit(-1); 

     BufferedReader in = null; 
     PrintWriter out = null; 

     try 
     { 
      // Create the streams to send and receive information 
      in = new BufferedReader(new InputStreamReader(s.getInputStream())); 
      out = new PrintWriter(new OutputStreamWriter(s.getOutputStream())); 

      // Since this is the client, we will initiate the talking. 
      // Send a string. 
      out.println("Hello"); 
      out.flush(); 
      // receive the reply. 
      System.out.println("Server Says : " + in.readLine()); 

      // Send a string. 
      out.println("This"); 
      out.flush(); 
      // receive a reply. 
      System.out.println("Server Says : " + in.readLine()); 

      // Send a string. 
      out.println("is"); 
      out.flush(); 
      // receive a reply. 
      System.out.println("Server Says : " + in.readLine()); 

      // Send a string. 
      out.println("a"); 
      out.flush(); 
      // receive a reply. 
      System.out.println("Server Says : " + in.readLine()); 

      // Send a string. 
      out.println("Test"); 
      out.flush(); 
      // receive a reply. 
      System.out.println("Server Says : " + in.readLine()); 

      // Send the special string to tell server to quit. 
      out.println("9"); 
      out.flush(); 
     } 
     catch(IOException ioe) 
     { 
      System.out.println("Exception during communication. Server probably closed connection."); 
     } 
     finally 
     { 
      try 
      { 
       // Close the streams 
       out.close(); 
       in.close(); 
       // Close the socket before quitting 
       s.close(); 
      } 
      catch(Exception e) 
      { 
       e.printStackTrace(); 
      }     
     }   
    } 
} 

私は、クライアントを実行すると、これが出力されます:

[[email protected] java]# /opt/jdk1.7.0_03/bin/java client 
Server Says : Hello 
Server Says : This 
Server Says : is 
Server Says : a 
Server Says : Test 
[[email protected] java]# 

私は、サーバーを実行すると、これはあります出力:

[[email protected] java]# ./server 
client connected to child thread -1215423632 with pid 2854. 
Hello 

This 

is 

a 

Test 

9 

9 

[[email protected] java]# 

ientがサーバーがクラッシュする接続を閉じます。私はスレッドを破壊することなく接続を閉じたい。どのように問題を解決できますか?

ベストこれは接続を受け入れ、元のスレッドコードである

P.Sを望みます。

void* thread_proc(void *arg) 
{ 
    int listensock, sock; 
    char buffer[25]; 
    int nread; 

    listensock = (int) arg; 

    while (1) { 
    sock = accept(listensock, NULL, NULL); 
    printf("client connected to child thread %i with pid %i.\n", pthread_self(), getpid()); 
    nread = recv(sock, buffer, 25, 0); 
    buffer[nread] = '\0'; 
    printf("%s\n", buffer); 
    send(sock, buffer, nread, 0); 
    close(sock); 
    printf("client disconnected from child thread %i with pid %i.\n", pthread_self(), getpid()); 
    } 
} 

このループは1つの文字列のみを受け入れ、それを返します。その後、終了します。私はwhileループでそれを修正しますが、内側のwhileループ(上記参照)ではサーバーがクラッシュします。 スレッドが多くの文字列を受け入れ、多くの文字列を送信できるように、コードを変更する方法はありますか?

答えて

1
while (1) { 
    sock = accept(listensock, NULL, NULL); 
    printf("client connected to child thread %i with pid %i.\n", pthread_self(), getpid()); 

    nread = 0; 
    while(nread >= 0) { 
     nread = recv(sock, buffer, 25, 0); 
     if (nread >= 0) { 
      buffer[nread] = '\0'; 
      printf("%s\n", buffer); 
      send(sock, buffer, nread, 0); 
     } 
    } 
    close(sock); 
    printf("client disconnected from child thread %i with pid %i.\n", pthread_self(), getpid()); 

}

3

あなたはソケットを閉じた後、内側のループから抜け出す必要がある - あなたは、閉じたソケットから読み取ろうとクラッシュしている:

while(1){ 
     nread = recv(sock, buffer, 25, 0); 
     buffer[nread] = '\0'; 
     printf("%s\n", buffer); 
     send(sock, buffer, nread, 0); 
     if(nread == '9'){ 
      close(sock); 
      break;  // <--- need to break out here 
     } 
    } 
+1

とのrecvをのためにチェックする必要があります0(相手側が接続を閉じたことを意味する)または-1(エラー)を返します。チャンスは 'nread == '9' 'も間違っています。受信したバイト数が57であるかどうかをチェックします。 – nos

+0

+1素晴らしいキャッチです。しかし、これはスレッドを終了させ、それはOPが望んでいないものです – GETah

+0

いいえ、それは内部のループを壊すだけです – nos

関連する問題