2011-02-21 7 views
0

私はサーバクライアントのJavaコードを持っており、サーバ部分はcで記述しなければなりません。 コードの最初の部分(サーバー側)は、クライアントからマルチキャストメッセージを受信し、TCP接続でクライアントに接続してメッセージを送信することです。私のCコードでは、クライアントからマルチキャストメッセージを受信できますが、TCP接続を試みるとエラーが発生します。 cサーバは、Javaクライアントとのtcp接続を確立できません。私は以下の両方のコードを掲載しています。問題が見つかった場合は、私に知らせてください。ありがとう。 CCサーバコード - JavaクライアントコードTCP接続問題

#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <time.h> 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <netdb.h> 
#include <pthread.h> 

void *listenToClient(); 
char *trim(char *str); 
void sendMessageToClient(char *ip, int *port, char *message); 

#define HELLO_PORT 6789 
#define HELLO_GROUP "228.5.6.7" 
#define MSGBUFSIZE 256 
char *ClientIP = "localhost"; 
char *HostIP = "192.168.164.138"; 
int isRunning = 1; 
main(int argc, char *argv[]) 
{ 
pthread_t thread; 
int th; 
th = pthread_create(&thread, NULL, listenToClient, NULL); 
pthread_join(thread, NULL);  
exit(0); 
} 

void *listenToClient(){ 
struct sockaddr_in addr; 
int fd, nbytes,addrlen; 
struct ip_mreq mreq; 
char msgbuf[MSGBUFSIZE]; 

u_int yes=1;     

/* create what looks like an ordinary UDP socket */ 
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) { 
    perror("socket"); 
    exit(1); 
} 

/* allow multiple sockets to use the same PORT number */ 
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) { 
    perror("Reusing ADDR failed"); 
    exit(1); 
    } 

/* set up destination address */ 
memset(&addr,0,sizeof(addr)); 
addr.sin_family=AF_INET; 
addr.sin_addr.s_addr=htonl(INADDR_ANY); 
addr.sin_port=htons(HELLO_PORT); 

/* bind to receive address */ 
if (bind(fd,(struct sockaddr *) &addr,sizeof(addr)) < 0) { 
    perror("bind"); 
    exit(1); 
} 

/* use setsockopt() to request that the kernel join a multicast group */ 
mreq.imr_multiaddr.s_addr=inet_addr(HELLO_GROUP); 
mreq.imr_interface.s_addr=htonl(INADDR_ANY); 

if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(mreq)) < 0) { 
    perror("setsockopt"); 
    exit(1); 
    } 

do {  
    addrlen=sizeof(addr); 
    if ((nbytes=recvfrom(fd,msgbuf,MSGBUFSIZE,0,(struct sockaddr *) &addr,&addrlen)) < 0) { 
     perror("recvfrom"); 
     exit(1); 
    } 
    puts(msgbuf); 
     char message[] = "FindIP:192.168.164.138 (Some IP)\n");  
    printf("\nSending Message To Client: %s\n", message); 
     sendMessageToClient(ClientIP, 8888, message); 
}while(isRunning==1); 
close(fd); 
} 

    /**Sends the messages to the remote machine 
    * ip = Address of the machine where message has to sent 
    * port = port used for sending the message 
    * message= string message 
    * 
    */ 
    void sendMessageToClient(char *ip, int *port, char *message) { 
int sockfd, portno, n; 
struct sockaddr_in serv_addr; 
struct hostent *server; 

char buffer[256]; 

portno = port; 
sockfd = socket(AF_INET, SOCK_STREAM, 0); 
if (sockfd < 0) 
    error("ERROR opening socket"); 
server = gethostbyname(ip); 
if (server == NULL) { 
    fprintf(stderr, "ERROR, no such host\n"); 
    exit(0); 
} 
bzero((char *) &serv_addr, sizeof(serv_addr)); 
serv_addr.sin_family = AF_INET; 
bcopy((char *) server->h_addr, (char *) &serv_addr.sin_addr.s_addr, 
     server->h_length); 
serv_addr.sin_port = htons(portno); 
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
    error("ERROR connecting"); 
bzero(buffer, 256); 
strcpy(buffer,message); 

n = send(sockfd, buffer, strlen(buffer), 0); 
if (n < 0) 
    error("ERROR writing to socket"); 
bzero(buffer, 256); 
close(sockfd); 
return 0; 
    } 
IPMulticastDiscoveryClient.javaクライアントコード

package org.postgresql.discovery; 
import java.net.DatagramPacket; 
import java.net.InetAddress; 
import java.net.MulticastSocket; 
import org.postgresql.discovery.ClientTCPResponseProvider; 
/** 

* A feature for detecting remote service addresses (IPs) via IP Multicast. 

* 

* Each service must first bind itself with the help of the IPMulticastDiscovery Server 

* and is identified with a unique name. 

* 
* 

* 

*/ 

public class IPMulticastDiscoveryClient { 
private static String myIp = null; 

public IPMulticastDiscoveryClient(){ 

} 

/** 

* Locates a bound service with a unique name via IPMulticast 

* 

* @param service unique name of the service 

* @return the IP address of the service as String 

* @throws Exception 

*/ 

public String getIpForService(String service, String host) throws Exception{ 

    //CloudCacheLogger.info("Looking for service: " + service); 

    // 1. open a response channel 

    ClientTCPResponseProvider response = new ClientTCPResponseProvider(service); 

    // 2. multicast request 

    sendJoinCluster(service, host); 

    // 3. collect response 

    //if(response.getFinalResult() == null){ 



    //} 

    try { 

     Thread.sleep(1000); 

    } catch (InterruptedException e) { 

     e.printStackTrace(); 

    } 



    String result = response.getFinalResult(); 

    //myIp = result.split(";")[1]; 

    //result = result.split(";")[0]; 



    // 4. close the response channel 

    response.destroy(); 

    // 5. check 

    if(result == null){ 

     throw new Exception("Could not discover service: " + service); 

    } else { 

     //CloudCacheLogger.info("found service: " + service + " at " + result); 

     return result; 

    } 

} 



/** 

* Uses a remote service to discover the local, external IP address 

* 

* @param service unique name of a remote service 

* @return the local, external ip address 

* @throws Exception 

*/ 

public String getMyIpFromService(String service) throws Exception{ 

    if(myIp != null) 

     return myIp; 

    else throw new Exception("could not determine local ip"); 

} 



private static void sendJoinCluster(String message, String host){ 

    try { 

     System.out.println("\nIn sendJoinCluster"); 

     InetAddress group = InetAddress.getByName(host); 

     MulticastSocket s = new MulticastSocket(9876); 

     s.joinGroup(group); 

     DatagramPacket hi = new DatagramPacket(message.getBytes(), message.length(),group, 6789); 

     s.send(hi); 

     s.leaveGroup(group); 

     s.close(); 



    } catch (Exception e){ 

     e.printStackTrace(); 

    } 

} 



public static void main (String args[]) throws Exception { 

    IPMulticastDiscoveryClient client = new IPMulticastDiscoveryClient(); 

    String result = client.getIpForService("FindIP", "228.5.6.7"); 

    System.out.println(result); 

} 

} 

ClientTCPResponseProvider.java

package org.postgresql.discovery; 

import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

/** 
* Offers a socket for receiving repsonses from remote services. Once the client 
sent a location 
* request, it waits for messages to arrive on this Socket. 
* 
* 
* 
*/ 
public class ClientTCPResponseProvider { 

private ServerSocket providerSocket; 
private Socket connection = null; 
private ObjectOutputStream out; 
private ObjectInputStream in; 

private boolean endConnection = false; 

private String keyword = null; 
private String finalResult = ""; 

public ClientTCPResponseProvider(String keyword){ 
    System.out.println("\nIn ClientTCPResponseProvider"); 
    this.keyword = keyword; 
    Thread t = new Thread(new ThreadedProvider()); 
    t.start(); 
} 

public void destroy(){ 
    endConnection = true; 
    try { 
     providerSocket.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

void goConnect(){ 
    try{ 
     System.out.println("\nIn goConnect."); 
     //1. creating a server socket 
     providerSocket = new ServerSocket(8888); 
     //2. Wait for connection 

     Object message = null; 

     long timeout = 1000; 
     long initTime = System.currentTimeMillis(); 

     do{ 
      //System.out.println("Waiting for connection..."); 
      connection = providerSocket.accept(); 
      //System.out.println("Connection received from " + connection.getInetAddress().getHostName()); 
      //3. get Input and Output streams 
      out = new ObjectOutputStream(connection.getOutputStream()); 
      out.flush(); 
      in = new ObjectInputStream(connection.getInputStream()); 
      //4. The two parts communicate via the input and output streams 
      try{ 
       message = in.readObject(); 
       String response = (String)message; 
       //System.out.println("received: " + response); 
       if(response.startsWith(keyword) && response.split(":")[0].equals(keyword)){ 
        finalResult += connection.getInetAddress().getHostAddress()+";"; 
        System.out.println(" IVAN " +finalResult); 
        //finalResult += connection.getLocalAddress().getHostAddress()+ ";"; 
        //endConnection = true; 
       } 
      } 
      catch(ClassNotFoundException classnot){ 
       System.err.println("Data received in unknown format"); 
      } 
      in.close(); 
      out.close(); 
      connection.close(); 
     } while(System.currentTimeMillis()-initTime < timeout); 
     providerSocket.close(); 
    } 
    catch(IOException ioException){ 
     ioException.printStackTrace(); 
    } 
} 

private class ThreadedProvider implements Runnable{ 
    //@Override 
    public void run() { 
     goConnect();  
    } 
} 

public String getFinalResult() { 
    return finalResult; 
} 

}

Serverコード

+0

「私はエラーがあります」 - 何がエラーですか? – Alnitak

答えて

0
portno = port; 

私はあなたが

portno = *port; 
+0

いいえ、私はそれが問題だとは思わない。 portnoを* portに変更すると、セグメンテーション違反が発生します。 – rmd22

+0

アプリは同じマシンで動作していますか? – Erik

+0

サーバーコードとJavaクライアントが異なるマシンで実行されていません。この問題は、cのconnect()コールで発生します。それは接続が拒否されたと言う。 – rmd22

0

をしたい疑うこの関数の宣言は正しくありません。

void sendMessageToClient(char *ip, int *port, char *message) 

portのタイプはint、ないint *でなければなりません。クライアントメッセージの送信元に関係なく、コードは常にlocalhost:8888に接続します。それはあなたが意図したものですか?

ちなみに、Cコードでは(bcopy(),bzero()gethostbyname()のような)多くの廃止された関数を使用しています。

+0

intポートをintポートに変更しましたが、同じ問題が引き続き発生します。私は192.168.164.138のIPを持つ別のマシンに接続しようとしています。私はこれを使用して正しいアドレスを渡していると思っていた - > bcopy((char *)server-> h_addr、(char *)serv_addr.sin_addr.s_addr、server-> h_length); ここで何が間違っていますか? – rmd22

+0

@ rmd22: 'server'は' gethostbyname(ip) 'の結果であり、' ip'は '' localhost "'である 'ClientIP'に相当します。 – caf

+0

@caf:localhostをclientipに変更しても、依然としてクライアントに接続できません。 : – rmd22