Chinaunix

标题: gsoap客户端接收中文字符问题 [打印本页]

作者: 阿飞侠    时间: 2006-12-29 10:40
标题: gsoap客户端接收中文字符问题
服务器端是java,客户端是标准C,用gsoap连服务器,函数返回的字符串要求是中文,但gsoap客户端接收到的是乱码,怎么解决啊?
作者: 阿飞侠    时间: 2007-01-04 11:41
没人回,我自己解决了。
soap_set_mode(&soap, SOAP_C_UTFSTRING);

然后客户端和服务器端发送接收字符都转成utf8格式就可以了。
作者: En_1981    时间: 2007-04-10 09:42
你是怎么装的gsoap,能不能告诉我一下,我研究好久,也不会
作者: eyeeye8317    时间: 2007-08-22 16:27
原帖由 阿飞侠 于 2007-1-4 11:41 发表
没人回,我自己解决了。
soap_set_mode(&soap, SOAP_C_UTFSTRING);

然后客户端和服务器端发送接收字符都转成utf8格式就可以了。


多谢了
我遇见同样的问题
找了很久
作者: eyeeye8317    时间: 2007-08-22 16:37
原帖由 En_1981 于 2007-4-10 09:42 发表
你是怎么装的gsoap,能不能告诉我一下,我研究好久,也不会


1 下载 gsoap The gSOAP package from http://sourceforge.net/projects/gsoap2

2 生成 h 文件 其中http://www.xmethods.net/wsdl/query.wsdl是soap服务器的文件
$ wsdl2h -o XMethodsQuery.h http://www.xmethods.net/wsdl/query.wsdl
或者
for c++
$ wsdl2h -s -o XMethodsQuery.h http://www.xmethods.net/wsdl/query.wsdl
或者
for c
$ wsdl2h -c -o XMethodsQuery.h http://www.xmethods.net/wsdl/query.wsdl

3 生成 soapC.cpp 等文件
$ soapcpp2 -C -Iimport XMethodsQuery.h

你可以看看
gSOAP 2.7.9 User Guide
http://www.cs.fsu.edu/~engelen/soapdoc2.html#tth_sEc8.
作者: wuxunfeng    时间: 2007-08-31 10:40
标题: wsdl2h 的问题
请问一下楼主,
$ wsdl2h -o XMethodsQuery.h http://www.xmethods.net/wsdl/query.wsdl
后面的那个http地址是什么意思呀?是不是到这个地址下载什么东西?
我编译的时候出现下面的错误,请教高手,这是什么问题啊
Saving test.h

Cannot open file 'typemap.dat'
Problem reading type map file typemap.dat.
Using internal type definitions for C++ instead.

Connecting to 'http://www.xmethods.net/wsdl/query.wsdl' to retrieve WSDL/XSD... connection failed
SOAP 1.1 fault: SOAP-ENV:Client [no subcode]
"Try Again"
Detail: get host by name failed in tcp_connect()
作者: growup    时间: 2007-08-31 23:17
wsdl2h根据.wsdl生成.h文件,上面这个ur是l官网手册中的例子,但这个url是不可用的。

换个别的.wsdl文件。gSoap源码里应该有范例的,找一下。
作者: dagun    时间: 2010-12-01 16:56
我也狂晕中,哪位朋友可以解决这个问题啊,楼上的朋友,给个解释吧?
作者: dagun    时间: 2010-12-01 17:00
我的服务端为php Apache服务器
客户端用gsoap C语言开发的客户端,现在遇到下面问题,谁可以给个解答,谢谢啦
SOAP 1.1 fault: SOAP-ENV:Client [no subcode]
"error in msg parsing:
Charset from HTTP Content-Type 'US-ASCII' does not match encoding from XML declaration 'UTF-8'
Detail:
Segmention fault

程序中我已经用函数做了设置soap_set_mode,但是还是有这个问题啊,是不是字符编码转换问题呢???请赐教。
作者: ecjtubaowp    时间: 2010-12-01 17:05
回复 9# dagun


    你转换成UTF-8看看。
作者: c/unix    时间: 2010-12-01 17:11
提示: 作者被禁止或删除 内容自动屏蔽
作者: dagun    时间: 2010-12-01 17:37
我在程序中转换了,但是还是不行啊。
服务器那边设置了utf-8编码,我在客户端程序这里也设置了,但是不可以,其实我只做了一个加法运算,./webcient 4 5就报错了,我在程序中对4和5这个两个字符串已经转换了,不解啊。能给个具体解释吗?兄弟,我第一次用这个东西。
作者: dagun    时间: 2010-12-01 17:39
为什么报这个错SOAP 1.1 fault: SOAP-ENV:Client [no subcode],谁给解释下。
作者: ecjtubaowp    时间: 2010-12-01 18:43
回复 12# dagun


    其实你按照sample下的例子根本就不需要转换编码什么的。
作者: dagun    时间: 2010-12-02 08:44
SOAP 1.1 fault: SOAP-ENV:Client [no subcode]
谁知道这个是什么意思?我猜是不是什么封装没有设置啊,因为看到.h文件有几个还没用到的函数,高手指点。
作者: c/unix    时间: 2010-12-02 09:03
提示: 作者被禁止或删除 内容自动屏蔽
作者: dagun    时间: 2010-12-02 10:43
我已经把输入的动作,值都转换编码了,没有之前的报错了。但是还是有这个错误
Error 200 fault: SOAP-ENV:Client [no subcode]
"Error 200"
Detail: [no detail]
Segmentation fault
这个是什么意思呢?
作者: ecjtubaowp    时间: 2010-12-02 10:49
回复 17# dagun


    贴代码吧!
作者: dagun    时间: 2010-12-02 10:49
回复 16# c/unix


    程序源文件?????????????
高手,具体说一下意思?我只是把输入参数信息转换了例如:
if (soap_call_ns2__myPlus(&soap, to_server, soap_actionnew, value.num1, value.num2, &result) == SOAP_OK)

soap不变,to_server不变,其他的我都转换编码了。result接收结果的,不转换编码。
作者: dagun    时间: 2010-12-02 11:01
其实代码很简单啊
服务器那里是php apache, 我同事说他定义的是utf-8编码
我在客户端这里只是想实现一个加法,但是就搞不定啊。
作者: dagun    时间: 2010-12-02 11:01
回复 11# c/unix


    请指点,这与程序源文件有啥关系啊?
作者: dagun    时间: 2010-12-02 11:03
我贴代码吧,大家不要笑话我啊,其实很简单的程序
#include "soapH.h"
#include "stdsoap2.h"
#include "HrNM3000ServiceBinding.nsmap"

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>                /* defines _POSIX_THREADS if pthreads are available */
#if defined(_POSIX_THREADS) || defined(_SC_THREADS)
#include <pthread.h>
#endif

#include <signal.h>                /* defines SIGPIPE */
#include <iconv.h>

#define FROM_CHARSET "gb2312"
#define TO_CHARSET "utf-8"
#define MAXCHARSETLEN 1024

const char server[] = "https://192.168.2.125/hrsoft/HrNM3000Service.php";

int convert_code(char *frombuf, char *tobuf, size_t *fromlen, size_t *tolen)
{
    iconv_t cd;

    cd = iconv_open(TO_CHARSET, FROM_CHARSET);
        if(cd < 0){
                printf("iconv_open error\n");
                return -1;
        }

    memset(tobuf, 0, *tolen);

    if (-1 == iconv(cd, &frombuf, fromlen, &tobuf, tolen)){
        printf("iconv err");
        return -1;
    }

    iconv_close(cd);
    return 0;
}

int CRYPTO_thread_setup();
void CRYPTO_thread_cleanup();
void sigpipe_handle(int);

int main(int argc, char **argv)
{
  struct soap soap;
  struct ns2__myPlus value;
// struct ns2__GetScada getvalue;
  char *from_value1 = NULL;
  char *from_value2 = NULL;
  char to_value1[10];
  char to_value2[10];
  char to_server[1024];
  char *soap_action = "usn:HrNM3000#myPlus";
  char soap_actionnew[1024];
  size_t to_action, from_action;
  size_t to_serverlen, from_serverlen;
  size_t to_len1, from_len1;
  size_t to_len2, from_len2;

  char *result = NULL;
  /* Init SSL */
  if(argc < 3)
  {
    printf("usage: %s a b\n", argv[0]);
    exit(0);
  }
  from_value1=argv[1];
  from_value2=argv[2];
from_len1 = strlen(from_value1);
from_len2 = strlen(from_value2);
from_serverlen = strlen(server);
from_action = strlen(soap_action);
to_len1 = to_len2 =to_serverlen=to_action= MAXCHARSETLEN;

//  setlocale(LC_ALL, "");
if(convert_code(from_value1, to_value1, &from_len1, &to_len1) < 0)
         printf("convert_code value1 failed\n");

if(convert_code(from_value2, to_value2, &from_len2, &to_len2) < 0)
         printf("convert_code value2 failed\n");

  if(convert_code(server, to_server, &from_serverlen, &to_serverlen) < 0)
         printf("convert_code server failed\n");

  if(convert_code(soap_action, soap_actionnew, &from_action, &to_action) < 0)
         printf("convert_code action failed\n");


//printf("to_value:%s %s\n", to_value1, to_value2);
  soap_ssl_init();
  if (CRYPTO_thread_setup())
  { fprintf(stderr, "Cannot setup thread mutex for OpenSSL\n");
    exit(1);
  }
  value.num1 = to_value1;
  value.num2 = to_value2;
//  getvalue.HostIP = to_value1;
// getvalue.name = to_value2;
  /* Init gSOAP context */
  soap_init(&soap);
// soap_set_mode(&soap, SOAP_C_UTFSTRING);
  //soap.mode |= SOAP_C_UTFSTRING;

  if (soap_ssl_client_context(&soap,
    /* SOAP_SSL_DEFAULT | SOAP_SSL_SKIP_HOST_CHECK, */        /* if we don't want the host name checks since these will change from machine to machine */
    SOAP_SSL_NO_AUTHENTICATION,        /* use SOAP_SSL_DEFAULT in production code */
    NULL,                 /* keyfile (cert+key): required only when client must authenticate to server (see SSL docs to create this file) */
    NULL,                 /* password to read the keyfile */
    NULL,        /* optional cacert file to store trusted certificates, use cacerts.pem for all public certificates issued by common CAs */
    NULL,                /* optional capath to directory with trusted certificates */
    NULL                /* if randfile!=NULL: use a file with random data to seed randomness */
  ))
  {
    printf("soap_ssl_client_context failed\n");
    soap_print_fault(&soap, stderr);
    exit(1);
  }
  soap.connect_timeout = 60;        /* try to connect for 1 minute */
  soap.send_timeout = soap.recv_timeout = 30;        /* if I/O stalls, then timeout after 30 seconds */
  if (soap_call_ns2__myPlus(&soap, to_server, soap_actionnew, value.num1, value.num2, &result) == SOAP_OK)
// if (soap_call_ns2__GetScada(&soap, server, "", getvalue.HostIP, getvalue.name, &result) == SOAP_OK)
// if (soap_call_ns2__GetScada(&soap, server, "", "", "", &result) == SOAP_OK)
    fprintf(stdout, "Result:%s\n", result);
  else
  {
    printf("error\n");
    soap_print_fault(&soap, stderr);
  }
  soap_destroy(&soap); /* C++ */
  soap_end(&soap);
  soap_done(&soap);
  CRYPTO_thread_cleanup();
  return 0;
}

/******************************************************************************\
*
*        OpenSSL
*
\******************************************************************************/

#ifdef WITH_OPENSSL

#if defined(WIN32)
# define MUTEX_TYPE                HANDLE
# define MUTEX_SETUP(x)                (x) = CreateMutex(NULL, FALSE, NULL)
# define MUTEX_CLEANUP(x)        CloseHandle(x)
# define MUTEX_LOCK(x)                WaitForSingleObject((x), INFINITE)
# define MUTEX_UNLOCK(x)        ReleaseMutex(x)
# define THREAD_ID                GetCurrentThreadId()
#elif defined(_POSIX_THREADS) || defined(_SC_THREADS)
# define MUTEX_TYPE                pthread_mutex_t
# define MUTEX_SETUP(x)                pthread_mutex_init(&(x), NULL)
# define MUTEX_CLEANUP(x)        pthread_mutex_destroy(&(x))
# define MUTEX_LOCK(x)                pthread_mutex_lock(&(x))
# define MUTEX_UNLOCK(x)        pthread_mutex_unlock(&(x))
# define THREAD_ID                pthread_self()
#else
# error "You must define mutex operations appropriate for your platform"
# error        "See OpenSSL /threads/th-lock.c on how to implement mutex on your platform"
#endif

struct CRYPTO_dynlock_value
{ MUTEX_TYPE mutex;
};

static MUTEX_TYPE *mutex_buf;

static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line)
{ struct CRYPTO_dynlock_value *value;
  value = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value));
  if (value)
    MUTEX_SETUP(value->mutex);
  return value;
}

static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)
{ if (mode & CRYPTO_LOCK)
    MUTEX_LOCK(l->mutex);
  else
    MUTEX_UNLOCK(l->mutex);
}

static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line)
{ MUTEX_CLEANUP(l->mutex);
  free(l);
}

void locking_function(int mode, int n, const char *file, int line)
{ if (mode & CRYPTO_LOCK)
    MUTEX_LOCK(mutex_buf[n]);
  else
    MUTEX_UNLOCK(mutex_buf[n]);
}

unsigned long id_function()
{ return (unsigned long)THREAD_ID;
}

int CRYPTO_thread_setup()
{ int i;
  mutex_buf = (MUTEX_TYPE*)malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
  if (!mutex_buf)
    return SOAP_EOM;
  for (i = 0; i < CRYPTO_num_locks(); i++)
    MUTEX_SETUP(mutex_buf[i]);
  CRYPTO_set_id_callback(id_function);
  CRYPTO_set_locking_callback(locking_function);
  CRYPTO_set_dynlock_create_callback(dyn_create_function);
  CRYPTO_set_dynlock_lock_callback(dyn_lock_function);
  CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function);
  return SOAP_OK;
}

void CRYPTO_thread_cleanup()
{ int i;
  if (!mutex_buf)
    return;
  CRYPTO_set_id_callback(NULL);
  CRYPTO_set_locking_callback(NULL);
  CRYPTO_set_dynlock_create_callback(NULL);
  CRYPTO_set_dynlock_lock_callback(NULL);
  CRYPTO_set_dynlock_destroy_callback(NULL);
  for (i = 0; i < CRYPTO_num_locks(); i++)
    MUTEX_CLEANUP(mutex_buf[i]);
  free(mutex_buf);
  mutex_buf = NULL;
}

#else

/* OpenSSL not used, e.g. GNUTLS is used */

int CRYPTO_thread_setup()
{ return SOAP_OK;
}

void CRYPTO_thread_cleanup()
{ }

#endif

/******************************************************************************\
*
*        SIGPIPE
*
\******************************************************************************/

void sigpipe_handle(int x) { }
作者: dagun    时间: 2010-12-02 11:03
我是借用了sslclient.c的程序
大家看有问题吗?
作者: adexbn    时间: 2010-12-02 11:05
UTFCSTRING正解。

如果实在不行,就两边都转码
作者: dagun    时间: 2010-12-02 11:09
大家给个具体解释啊。。。。
作者: dagun    时间: 2010-12-06 14:35
对于这种客户端和服务端通信的问题,有时候不一定是客户端的问题,也许是服务端的问题。解决问题最好办法是在服务端设置打印信息,查看客户端给服务端发过来的SOAP头信息,以及编码格式,以及服务端是否收到过来的信息等。呵呵
关键不是问题,而是我们没有找到解决问题的方法。
作者: dagun    时间: 2010-12-06 14:39
现在问题是发现,如果服务端信息超过1024字节,会压缩数据gzip形式,发到客户端。我看过英文资料,说是接受时候会自动解压缩的,但是我发现如果数据过长后,客户端没有进行解压缩数据。打出如下信息:
Error 200 fault: SOAP-ENV:Client [no subcode]
"Error 200"
Detail: [no detail]

谁可以解决这个问题,相关设置我已经做过,但是还是有问题啊。
作者: dagun    时间: 2010-12-06 16:10
还没人回答这个问题吗,也就说客户端这边怎么设置呢?我觉得客户端没有自动去解压服务端发来的数据啊。期待。。。。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2