【发布时间】:2013-10-04 11:00:53
【问题描述】:
我正在尝试在客户端实现 select(..),方法是创建多个套接字,除了 TCP 套接字之外,还从服务器到 recv(..)。我想接收使用 select(..) 创建的不同套接字的不同 recv(..) 上的数据。代码似乎没有按预期运行。请帮忙。谢谢!
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int count, createsocket, chunks, newsocket[5], i;
int bufsize = 2048;
char *buffer = malloc(bufsize);
char fname[256];
struct sockaddr_in address;
fd_set master;
fd_set read_fds;
int fdmax, j;
FD_ZERO(&master);
FD_ZERO(&read_fds);
if((createsocket = socket(AF_INET, SOCK_STREAM, 0)) > 0)
{
printf("Socket created.\n");
}
address.sin_family = AF_INET;
address.sin_port = htons(15001);
inet_pton(AF_INET, argv[1], &address.sin_addr);
if(connect(createsocket, (struct sockaddr*)&address, sizeof(address)) == 0)
{
printf("Connected to server %s\n",argv[1]);
}
printf("Enter the file name to download\n");
scanf("%s",fname);
send(createsocket, fname, sizeof(fname), 0);
// printf("Enter the chunks of file to receive");
printf("waiting to receive the file from server..\n");
//code to create a new socket based on the number of chunks required
for(i=0;i<4;i++)
{
if((newsocket[i] = socket(AF_INET, SOCK_STREAM, 0)) > 0)
{
printf("new Socket %d created.\n", i);
}
}
FD_SET(createsocket, &master);
fdmax = createsocket;
for(;;)
{
read_fds = master;
if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1){
perror("select");
exit(2);
}
for(i=0; i<=fdmax; i++){
if(FD_ISSET(i, &read_fds)) {
if(i == createsocket) {
printf("something is happening..\n");
if(newsocket[i] == -1){
printf("socket %d\n",i);
} else {
FD_SET(newsocket[i], &master);
if(newsocket[i] > fdmax) {
fdmax = newsocket[i];
}
printf("still something is going on..\n");
}
} else {
printf("Doing something..\n");
for(j = 0; j <= fdmax; j++) {
if(FD_ISSET(j, &master)) {
if(j!= createsocket && j!= i) {
if((count = recv(createsocket, buffer, bufsize, 0)) > 0) {
perror("recv");
} else {
write(1, buffer, count);
}
}
}
}
}
}
}
}
// while((count = recv(createsocket, buffer, bufsize, 0)) > 0)
// write(1, buffer, count);
printf("EOF.\n");
for(i=0;i<4;i++)
{
close(newsocket[i]);
}
return close(createsocket);
}
【问题讨论】:
-
“似乎没有按预期运行”不是可接受的问题描述。请提供更多信息。
-
@EJP 好吧,在带有 tcp 连接的客户端上使用 select 我正在尝试创建一些新的套接字来接收来自连接的 tcp 服务器的数据。因为,recv 是一个阻塞协议,所以我使用 select(..) 在客户端的不同新创建的套接字上从服务器接收数据。事情有点清楚了吗?
-
@EJP 客户端创建 k 个 TCP 套接字(每个用于分块接收的块)并使用“select(...)”函数进行异步 IO。也就是说,客户端并行下载块,并使用 IO 多路复用而不是多线程。当收到所有块时,它只是将块合并到一个文件中。
-
开始时,尝试让 select 仅使用 一个 套接字可能是个好主意。
-
@alk 我从一个套接字开始,它正在工作。我意识到我创建的其他套接字是悬空的并且无论如何都没有连接到服务器。一个套接字正在工作,因为它已经通过 tcp 连接连接到服务器。有什么方法可以将客户端的多个套接字连接到同一台服务器?