Sockets 选择套接字调用发送和接收同步
我正在使用select呼叫并接受来自“X”个客户端的连接。 我进行了双工连接,即服务器到客户端和客户端到服务器。 当两个实体之间建立连接时,我将发送 从一个实体到另一个实体的数据块。 在发送过程中,我以块的形式读取一个文件,并以块的形式发送数据Sockets 选择套接字调用发送和接收同步,sockets,network-programming,Sockets,Network Programming,我正在使用select呼叫并接受来自“X”个客户端的连接。 我进行了双工连接,即服务器到客户端和客户端到服务器。 当两个实体之间建立连接时,我将发送 从一个实体到另一个实体的数据块。 在发送过程中,我以块的形式读取一个文件,并以块的形式发送数据 while(file_size !=0) { read_bytes = read(fd, buff, sizeof(buff)); cnt_ = send(_sock_fd,buff,actually_read,0); file_
while(file_size !=0)
{
read_bytes = read(fd, buff, sizeof(buff));
cnt_ = send(_sock_fd,buff,actually_read,0);
file_size = file_size - cnt_;
printf("total sent remaining %d : %d\n",size,actually_read);
}
在接收端时
//首先,我发送包含大小的头,它被很好地接受,但在接下来的发送调用中,我使用了“get_readable_bytes”(使用ioctl),它返回到达套接字的字节数
`while(大小!=0)
{
int检验=0
while(((cnt_= get_readable_bytes(_sock_fd))== 0) )//&& test_ == 0
{
cnt_= get_n_readable_bytes(_sock_fd);
printf("Total bytes recved %d\n",cnt_);
//test_ = test_ + 1;
}
while(cnt_ != 0)
{
actually_read = recv(_sock_fd, buff, sizeof(buff),0);
int _cnt = get_n_readable_bytes(_sock_fd);
printf("Total bytes recved %d\n",cnt_-_cnt);
write(_fd,buff,actually_read);
cnt_ = cnt_ - actually_read;
test_ = 0;
}
`现在的问题是
1.在执行接收功能的过程中,控制自动转到选择功能,并尝试再次执行整个接收功能,因此是否有任何方法同步发送方和接收方,以便在发送方完成后启动接收方或发送方启动接收方?
2.如何维护发送和接收的字节数。
这是我的选择电话
`is_read_availble = select(maxfd + 1,&read_set,NULL,NULL,&timeout)`
超时10秒。概述您需要的缓冲区代码类型。(为了允许部分读/写,缓冲区需要在调用之间保持不变)顺便说一句:您确实需要处理read()和write()的-1返回,因为它们会严重干扰您的缓冲区簿记。EINTR+EAGAIN/EWOULDBLOCK非常常见
struct buff {
unsigned size;
unsigned bot;
unsigned top;
char *buff;
};
struct buff bf = {0,0,0,NULL};
initialisation:
bf.buff = malloc(SOME_SIZE);
/* ... error checking omitted */
bp.size = SOME_SIZE;
bp.bot = bp.top =0;
reading:
unsigned todo;
int rc;
/* (maybe) shift the buffer down to make place */
todo = bf.top - bf.bot;
if (todo) {
memmove (bf.buff, bf.buff + bf.bot, todo);
bf.top = todo; bf.bot = 0;
}
todo = bf.size - bf.top;
if (!todo) { /* maybe throttle? ... */ return; }
rc = read (fd, bf.buff+bp.top, todo);
/* ... error checking omitted */
if (rc == -1) switch (errno) {...}
else if (rc == 0) {...}
else {
total_read += rc;
bp.top += rc;
}
writing:
unsigned todo;
int rc;
todo = bf.top - bf.bot;
if (!todo) { /* maybe juggle fd_set ... */ return; }
rc = write (fd, bf.buff+bp.bot, todo);
/* ... error checking omitted */
if (rc == -1) switch (errno) {...}
else if (rc ==0) { ...}
else {
bp.bot += rc;
total_written += rc;
if (bp.bot == bp.top) bp.bot = bp.top =0;
}
/* ... this is the place to juggle the fd_set for writing */
好的:不要将函数的写入部分放在select部分的读取处理程序中,而不是。要么在select循环中为写入设置一个额外的fd_集,要么每次都检查读取缓冲区中是否还有要写入的内容。调用select()当你仍然有工作要做时,是什么阻碍了你。在大多数情况下,每个(对)文件描述符都有某种缓冲区结构是很方便的。我认为这一个可能会对你有所帮助: