2011-07-24 21 views
7

मैं एक सी प्रोग्राम और एक पायथन स्क्रिप्ट के बीच संवाद करने के लिए यूनिक्स डोमेन सॉकेट का उपयोग करने की कोशिश कर रहा हूं। पायथन स्क्रिप्ट सी प्रोग्राम में यूनिक्स डोमेन सॉकेट के माध्यम से डेटा भेजती है।सी और पायथन - सॉकेट के साथ संचार

import socket 

s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 
s.connect("/tmp/demo_socket") 
print "Sending..." 
s.send("Hello world") 
x = s.recv(1024) 
print x 
s.close() 

अजगर स्क्रिप्ट के साथ विफल रहता है:

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/un.h> 
#include <sys/types.h> 
#include <sys/socket.h>  
#define UNIX_PATH_MAX 100 

int main(void) 
{ 
struct sockaddr_un address; 
int socket_fd, connection_fd; 
socklen_t address_length; 
pid_t child; 

socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); 
if (socket_fd < 0){ 
    printf("socket() failed\n"); 
    return 1; 
} 

unlink("/tmp/demo_socket"); 
memset(&address, 0, sizeof(struct sockaddr_un)); 

address.sun_family = AF_UNIX; 
snprintf(address.sun_path, UNIX_PATH_MAX, "/tmp/demo_socket"); 

if (bind(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) { 
    printf("bind() failed\n"); 
    return 1; 
} 
if(listen(socket_fd, 5) != 0) { 
    printf("listen() failed\n"); 
    return 1; 
} 

//----------------WHILE LOOP-----------------------> 
while((connection_fd = accept(socket_fd, 
          (struct sockaddr *) &address, 
          &address_length)) > -1) 
{ 
. 
. 
.(doesn't get any further than this) 

यह अजगर स्क्रिप्ट मैं सॉकेट के लिए एक संदेश भेजने के लिए उपयोग कर रहा हूँ है:

यहाँ मेरी सी कार्यक्रम से प्रासंगिक कोड है त्रुटि "टूटी हुई पाइप"। सी प्रोग्राम कभी भी लूप में प्रवेश नहीं करता है क्योंकि स्वीकृति() फ़ंक्शन विफल रहता है और '-1' देता है।

स्वीकार क्यों() विफल रहा है? और मैं इसे सफल बनाने के लिए क्या कर सकता हूं?

+0

प्रिंट बाहर 'errno': अपनी सी कोड में (या बेहतर' strerror (errno) ') जब स्वीकार विफल रहता है। वह और मैन पेज आपको कम से कम उत्तर का हिस्सा बताएगा। – Mat

+0

यह त्रुटि "अवैध तर्क" में विफल रहता है। –

उत्तर

2

an example I found पर देखकर, ऐसा लगता है कि bind को पारित करने वाली लंबाई sockaddr_un में समाप्ति या पैडिंग नल की गणना नहीं करनी चाहिए।

प्रयास करें:

size_t addrlen; 
const char* sockname = "/tmp/demo_socket"; 

/* ... */ 

address.sun_family = AF_UNIX; 
snprintf(address.sun_path, UNIX_PATH_MAX, sockname); 
addrlen = sizeof(address.sun_family) + strlen(sockname); 

if (bind(socket_fd, (struct sockaddr *) &address, addrlen) != 0) { 
    printf("bind() failed\n"); 
    return 1; 
} 

पी.एस. इस वजह से, आपको memset कॉल की आवश्यकता नहीं है।

2

आईआईआरसी, address_lengthaccept() कॉल से पहले sockaddr_un के आकार में प्रारंभ करने की आवश्यकता है। कॉल के दौरान, यह पीयर पते की वास्तविक लंबाई से भरा हुआ है जो address में स्थानांतरित हो गया है।

Rgds, मार्टिन

+0

एर ... ओह, हाँ। धन्यवाद! –

+0

शानदार! अपनी टिप पढ़ने के बाद, और थोड़ा गुगल, मैं सेटिंग द्वारा समाधान के साथ आया: address_length = sizeof (पता); मेरे स्वीकार करने से पहले() कॉल करें। धन्यवाद! –

संबंधित मुद्दे