我怀疑这有一个我忽略的简单解决方案,可能与客户端或它的设置方式有关。
无论如何,我正在尝试设置一个简单的 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;
}
之后,我通过在 guest 计算机中打开另一个终端并键入“telnet localhost 8888”并输入我想要的任何字符串来对其进行测试。
这个测试现在运行良好,在我的 Windows 机器上创建套接字编程的客户端:
#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 VM 有关,但我不确定。
---更新--- 更新了意外分号并添加了 WSAGetLastError,它显示错误代码 10061;这转化为 “连接被拒绝。 由于目标计算机主动拒绝,无法建立连接。这通常是由于尝试连接到外部主机上不活动的服务而导致的——也就是说,没有运行服务器应用程序的服务。”
最佳答案
[第三次编辑后:]
抱歉,请重新阅读您的问题。重要的是:
The virtual machine I am setting to run the server c code, and the Windows will be running the client.
127.0.0.1 是一个始终仅本地 到启用 IP 框的地址。因此,您的服务器正在监听 Linux VM 本地接口(interface) 127.0.0.1,客户端尝试连接到 Windows 机器本地的 127.0.0.0。这两个界面不相同。结果很明显,即客户端找不到要连接的任何内容。
127.0.0.1(所谓的“IPv4 本地环回接口(interface)e”)只能用于本地到一个盒子的连接.
关于连接到本地虚拟机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46781455/