我有一个数据采集模块,我想从以太网端口收集数据。--我是按步骤到达的,目前我只想从客户端向服务器发送connect。我使用了Beej的指南来获得基本的C代码。但是我一直得到这个连接错误connect: Connection refused.
这就是我要做的:
在启动客户端应用程序之前,对于服务器端应用程序returns还是服务器端应用程序有一个疑问,那么我应该继续运行它(while(1);),以便能够从客户端连接到它吗?
我忘了什么事了吗?帮助!
我在这里粘贴服务器端和客户端的非常修改(IP和端口号不同)的C代码:
Server.c
/*
** server.c
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
// code for a server waiting for connections
// namely a stream socket on port 3490, on this host's IP
// either IPv4 or IPv6.
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP address
if ((rv = getaddrinfo(NULL, "50000", &hints, &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}
// loop through all the results and bind to the first we can
for(p = servinfo; p != NULL; p = p->ai_next)
{
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1)
{
perror("socket");
continue;
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1)
{
close(sockfd);
perror("bind");
continue;
}
break; // if we get here, we must have connected successfully
}
if (p == NULL)
{
// looped off the end of the list with no successful bind
fprintf(stderr, "failed to bind socket\n");
exit(2);
}
freeaddrinfo(servinfo); // all done with this structure
}Client.c
/*
** client.c
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
// code for a client connecting to a server
// namely a stream socket to www.example.com on port 80 (http)
// either IPv4 or IPv6
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use AF_INET6 to force IPv6
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo("192.168.2.4", "50000", &hints, &servinfo)) != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}
// loop through all the results and connect to the first we can
for(p = servinfo; p != NULL; p = p->ai_next)
{
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1)
{
perror("socket");
continue;
}
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1)
{
close(sockfd);
perror("connect");
continue;
}
break; // if we get here, we must have connected successfully
}
if (p == NULL)
{
// looped off the end of the list with no connection
fprintf(stderr, "failed to connect\n");
exit(2);
}
freeaddrinfo(servinfo); // all done with this structure
}发布于 2012-07-16 03:24:25
您的服务器代码缺少listen()和accept()代码来“等待”连接,方法是调用listen(),然后执行accept()来接受新的连接。您使用的示例不是演示了如何做到这一点吗?通常,您还将为每个新连接发送一个新线程。
有关详细信息,请参阅C++/socket.htm。
下面是一个更完整的实现的链接:http://www.thegeekstuff.com/2011/12/c-socket-programming/
发布于 2012-07-16 03:32:42
是的,你需要保持服务器程序运行。在您的服务器程序中,您已经使用socket()创建了套接字并绑定到一个地址bind(),现在您需要开始侦听传入的连接。这是通过listen()调用完成的。一旦套接字侦听传入的连接,您就必须使用accept()调用来实际接受连接,并获取套接字与该特定客户端进行通信。
作为一个快速示例,在freeaddrinfo之后您可以添加以下代码:
listen(sockfd, 8); /* allow up to 8 pending connections, i.e. created but not accepted */
while (1) {
int clientfd;
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(struct sockaddr_in);
clientfd = accept(sockfd, &client_addr, &client_addr_len);
/* communicate with client by send()/recv() or write()/read() on clientfd */
close(clientfd);
}此代码的缺点是一次只处理一个客户端。有几种方法可以同时处理多个客户端:使用fork()的多个进程、多个线程或轮询。我认为,上述每一种做法都超出了这一问题的范围。
发布于 2012-07-16 03:25:49
请查看您的Server.c文件:它根本不调用listen()!
如果目标服务器没有在指定端口上侦听,那么它将在从客户端接收到SYN数据包时返回RST数据包,因此connect()将以"Connection refused“返回。
服务器端的正常功能流是套接字->绑定->侦听->接受:
getaddrinfo();
socket();
bind();
listen();
/* accept() goes here */ 请参阅https://beej.us/guide/bgnet/html/multi/syscalls.html#listen
https://stackoverflow.com/questions/11497716
复制相似问题