2012-03-03 82 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]# 

当cl客户端关闭服务器崩溃的连接。我想在不破坏线程的情况下关闭连接。我如何解决这个问题?

最佳希望

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()); 
    } 
} 

此循环将只接受一个字符串并将返回它。然后将退出。我使用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 2012-03-03 20:44:15

+0

+1 nice catch。但是,这将使线程退出,这不是OP想要的 – GETah 2012-03-03 20:45:19

+0

不,它只会打破内部循环 – nos 2012-03-03 20:46:14

相关问题