Java和c++之间的套接字通信

Socket communication between Java and C++

本文关键字:套接字 通信 之间 c++ Java      更新时间:2023-10-16

我正在尝试在Java服务器和c++客户端之间建立连接。但是当我在我的客户端读取数据时,我总是有相同的奇怪字符(í)。我试图改变两边的编码,但没有工作。

下面是我的Java代码:
public class Serveur
{
    public static void main(String[] args) throws Exception
    {
        final int PORT = 13370;
        try
        {
            ServerSocket service= new ServerSocket(PORT);
            Socket connection = service.accept();
            PrintWriter pw = new PrintWriter(connection.getOutputStream());
            String s = Integer.toString(5);
            while(true)
            {
                pw.print(s.getBytes("UTF-8"));
                pw.flush();
                pw.close();
            }
            connection.close();
        }
}

我还尝试使用OutputStream, DataOutputStream和BufferedOutputStream。

下面是c++代码:
int main(int argc, char* argv[])
{
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);
    SOCKET sock;
    SOCKADDR_IN sin;
    char buffer[512];
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    sin.sin_family      = AF_INET;
    sin.sin_port        = htons(13370);
    sock = socket(AF_INET,SOCK_STREAM,0);
    if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
{
    cout<<"connection"<<endl;
    if(recv(sock, buffer, sizeof(buffer), 0) != SOCKET_ERROR)
    {
        string s = buffer;
        wchar_t *pwchello = L"Hi";
        wchar_t *pwc      = (wchar_t *)malloc( sizeof( wchar_t ));
        char    *pmbhello = buffer;
        int i = mbstowcs(pwc,pmbhello, MB_CUR_MAX);
        cout << i << endl;
        cout<<"cout : "<<pwc<<endl;
        cout <<buffer<<endl;
        printf("printf : %sn", buffer);
        cout << "wsagetlasterror() : "<<WSAGetLastError();
        closesocket(sock);
        WSACleanup();
        free(m_pBuffer);
    }
    return 0;
}

正如你所看到的,我尝试了不同的解决方案,但都没有成功。

提前感谢,对不起,我的英语可能不是很好

您混淆了许多不同的编码转换和I/O策略。您应该尝试下面的简化版本:

if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
{
    cout << "connection" << endl;
    // the result of 'recv()' is either SOCKET_ERROR or
    // the number of bytes received.  don't though away
    // the return value.
    const int result = recv(sock, buffer, sizeof(buffer), 0);
    if(result != SOCKET_ERROR)
    {
        // use length (in bytes) returned by 'recv()'
        // since buffer is not null terminated.
        string s(buffer,result);
        // 's' is in UTF-8 no converstion to wide strings
        // should be necessary.
        cout << "message: '" << s << "'." << endl;
    }
    closesocket(sock);
}
WSACleanup();

但是,请注意,标准输出在当前代码页中,通常UTF-8不是默认代码页。在windows中将Unicode数据输出到控制台需要调用一些其他库来配置。

recv不会将其目标缓冲区转换为以空结尾的字符串。它在缓冲区中填充一定数量的字节,但不追加一个0。

你需要这样做(当然,有错误检查):

ssize_t bytesRead = recv(buffer, ...);
string str(buffer, bytesRead);

另外,要注意recv并不能保证在一次调用中发送的内容在一次调用中被接收(除非您使用UDP)。

这里只为单个wchar_t分配空间:

wchar_t *pwc = (wchar_t *)malloc( sizeof( wchar_t ));

您也将缓冲区分配给字符串s,但似乎从未使用s

从昨晚开始我就一直有同样的问题。最后发现编码不被我的服务器识别(用C写的),所以我在客户端修改了

someOutputStream.writeUTF(someSillyString);

someOutputStream.write(someSillyString.getBytes());

这样,我甚至不需要在服务器端进行类型转换。