2017-10-17 192 views
1

我怀疑这有一个简单的解决方案,我忽略了,可能与客户端或如何设置。
无论如何,我试图建立一个简单的Echo服务器/客户端来了解套接字编程的基础知识。我有一台运行Linux Mint的虚拟机,主机运行的是Windows 10.我设置的虚拟机运行服务器c代码,Windows将运行客户端。连接到本地虚拟机

我开始做服务器代码

//Echo Server for UNIX: Using socket programming in C, a client sends a string 
//to this server, and the server responds with the same string sent back to the client 

#include <stdio.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <unistd.h> 
#include <string.h> 

int main() 
{ 
    char stringBuffer[50]; //string buffer for reading incoming and resending 
    int listener, communicator, c; //store values returned by socket system call 

    if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) //creates a new socket 
     puts("Could not create socket"); 
    puts("Socket Created"); 

    struct sockaddr_in servAddr, client; //structure from <netinet/in.h> for address of server 
    servAddr.sin_family = AF_INET; //addressing scheme set to IP 
    servAddr.sin_port = htons(8888); //server listens to port 5000 
    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //symbolic constant of server IP address 

    //binds the socket to the address of the current host and port# the server will run on 
    if (bind(listener, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0){ 
     puts("Bind failed"); 
     return 1; 
    } 
    puts("Bind Successful"); 

    listen(listener, 5); //listens for up to 5 connections at a time 
    c = sizeof(struct sockaddr_in); 
    if ((communicator = accept(listener, (struct sockaddr*)&client, (socklen_t*)&c))<0) 
     puts("accept failed"); 
    puts("Connection Accepted"); 
    //wait until someone wants to connect, then whatever is sent can be read from communicator, which can then be sent back 

    while(1){ 
     bzero(stringBuffer, 50); //sets buffer to 0 
     read(communicator, stringBuffer, 50); //reads from communicator into buffer 
     write(communicator, stringBuffer, strlen(stringBuffer)+1); //returns back 
    } 
    return 0; 
} 

之后,我测试了它在客户机打开另一个终端和类型“远程登录本地主机8888”,并输入我想任何字符串。

这个测试已经摸索的话,到我的Windows机器上创建的socket编程的客户端:现在

#include <winsock.h> 
#include <stdio.h> 
#include <string.h> 
#pragma comment(lib,"ws2_32.lib") //Winsock Library 

int main(int argc, char *argv[]) 
{ 

    WSADATA wsadata; //variable for using sockets in windows 
    SOCKET sock; //socket variable for network commands 
    char sendString[50], recieveString[50]; //variables for sending and recieving messages to/from server 

    //check if WSA initialises correctly 
    if (WSAStartup(MAKEWORD(2,2), &wsadata) != 0) 
     printf("Error Code: %d", WSAGetLastError()); 

    //creates new socket and saves into sock 
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 
     printf("Could not create socket: %d", WSAGetLastError()); 
    printf("Socket created\n"); 

    struct sockaddr_in servAddr; 
    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //sets the IP address to the same machine as the server 
    servAddr.sin_family = AF_INET; //addressing scheme set to TCP/IP 
    servAddr.sin_port = htons(8888); //server address is on port 8888 

    //connects to device with specifications from servAddr 
    if (connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) { 
     printf("Connection Error %d\n", WSAGetLastError()); 
     return 1; 
    } 
    printf("Connection Accepted\n"); 

    while(1){ 
     fgets(sendString, 50, stdin); //uses stdin to get input to put into sendString 
     //sends sendString to server using sock's properties 
     if (send(sock, sendString, strlen(sendString) + 1, 0) < 0); { 
      printf("Send Failed"); 
      return 0; 
     } 

     //reads from server into recieveString 
     if ((recv(sock, recieveString, 50, 0)) == SOCKET_ERROR) 
      printf("Recieve Failed"); 
     printf("%s", recieveString); //prints out recieveString 
    } 
} 

,与服务器仍在运行,当我尝试了客户端,我得到响应“连接错误”(来自第35行)。看了Unix和WinSock的例子,我不确定为什么我会失败连接。我怀疑它可能与Windows到Linux虚拟机有关,但我不确定。

--- UPDATE --- 更新了意外分号并添加了WSAGetLastError后,显示的错误代码为10061;这将转换为 “连接被拒绝 由于目标计算机主动拒绝连接,因此尝试连接到外部主机上处于非活动状态的服务(即没有运行服务器应用程序的服务)会导致无法建立连接。 “

+2

if语句后为什么会有分号?第34行 – Kishor

+0

'c'应该是'socklen_t' * not *'int'! – alk

+0

你*在同一个盒子上运行服务器和客户端,不是吗? – alk

回答

3

[第三次编辑后:]

Sry,只是重新读你的问题。重要的是这里:

我设置的虚拟机运行服务器c代码,并且Windows将运行客户端。

127.0.0.1是一个地址总是只是本地到支持IP框。因此,您的服务器正在侦听Linux虚拟机本地的接口127.0.0.1,并且客户端尝试连接到Windows本地的127.0.0.0。那两个接口是不是一样。结果很明显,即客户端找不到任何连接。

127.0.0.1(即所谓的 “IPv4的本地回环interfac E”)只能用于连接当地准确一个框。

+0

好吧,回答为什么,问题将是什么知识产权我使用那么? – RELENTLESS00G

+0

服务器主机的错误IP? – EJP

+0

也就是说,我也尝试使用INADDR_ANY服务器,但客户端发送到哪个IP? - 编辑:好吧,他们真的在网络上看到彼此完全不同的东西吗?我不确定IP地址是如何真正用于访客机器的,对不起 – RELENTLESS00G

3
if (connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0); { 
    printf("Connection Error"); 
    return 1; 
} 

这只是一个微不足道的语法错误。您无条件地进入该块。删除第一个分号。

然而,还有一个更重要的要点。当您从系统调用(如connect())中收到错误时,必须打印的错误。不只是你自己设计的一些信息。否则,你不知道你是否有一个错误,或一个暂时的问题,或一个长期的问题,或一个永久的问题。

更改printf()到:

printf("Connect error %s\n", WSAGetLastError()); 

然后继续如同错误没有发生。

注意,这适用于所有系统来电,具体包括socket()bind()listen()connect()accept()recv()send(),和朋友。

+0

对不起,我忽略了分号,但它确实不是问题所在。不知道为什么我忘记了该行的WSAGetLastError(),但没有其他的,谢谢你指出。我已经更新了当前的错误代码和翻译。 – RELENTLESS00G

+1

这真的是*问题。现在的问题是WSAECONNREFUSED,它仅仅意味着在您尝试连接的IP:端口上没有任何监听。 – EJP

+0

在我作出条件陈述以查明问题出在哪里之前,它没有奏效;这是一个问题,但只是在检查问题出在哪里时才引入。现在的问题是,为什么会出现这种错误?在我的服务器中有一个在该IP的监听器:端口 – RELENTLESS00G