socket非阻塞模式出现operation now in process ,请大家帮忙看看!

reality 2008-05-14 02:21:35
代码如下:

#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket() and bind() */
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h> /* for atoi() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#include <fcntl.h>
#define TCPCLIENTPORT 10000
#define BUFFERSIZE 256
int main()
{

struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
int sock,tcpsock;
socklen_t addr_len;
int len,tcplen;
char buff[BUFFERSIZE],tcprecvbuff[BUFFERSIZE];

struct sockaddr_in tcp_seraddr;
char *SerIP = "192.168.1.115";

if ((tcpsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
perror("socket() failed");
exit(0);
}
/* Construct the server address structure */
fcntl(tcpsock,F_SETFL,O_NONBLOCK); //错误出在这里

memset(&tcp_seraddr, 0, sizeof(tcp_seraddr)); /* Zero out structure */
tcp_seraddr.sin_family = AF_INET; /* Internet address family */
tcp_seraddr.sin_port = htons(TCPCLIENTPORT); /* Server port */
tcp_seraddr.sin_addr.s_addr = inet_addr(SerIP); /* Server IP address */

/* Establish the connection to the echo server */
if (connect(tcpsock, (struct sockaddr *) &tcp_seraddr, sizeof(tcp_seraddr)) < 0)
{
perror("connect() failed");
exit(0);
}
return 0;
}
...全文
8035 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
stucsz 2010-03-29
  • 打赏
  • 举报
回复
为什么要把fcntl()放到connect()后面呢?在5L的例程中不是放在connect()的前面吗?
reality 2008-05-19
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 SimpCL 的回复:]
LZ可以把 fcntl(tcpsock,F_SETFL,O_NONBLOCK); 放到connect之后就好了!
个人觉得在connect之前就设nonblock不太妥吧:)
[/Quote]
把 fcntl(tcpsock,F_SETFL,O_NONBLOCK); 放到connect后面,程序修改成功。
大家所提的各种方法应该没错,只是我的程序的问题。谢谢大家
SimpCL 2008-05-15
  • 打赏
  • 举报
回复
LZ可以把 fcntl(tcpsock,F_SETFL,O_NONBLOCK); 放到connect之后就好了!
个人觉得在connect之前就设nonblock不太妥吧:)
威廉-丁 2008-05-14
  • 打赏
  • 举报
回复
客户端程序:
#include<stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define SERVPORT 3333
#define MAXDATASIZE 100 /*每次最大数据传输量 */

main(int argc, char *argv[]){
int sockfd, recvbytes;
char buf[MAXDATASIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if (argc<2)
{
fprintf(stderr,"Please enter the server's hostname!\n");
exit(1);
}
 if((host=gethostbyname(argv[1]))==NULL) {
herror("gethostbyname出错!");
exit(1);
}
 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket创建出错!");
exit(1);
}
 serv_addr.sin_family=AF_INET;
 serv_addr.sin_port=htons(SERVPORT);
 serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
 bzero(&(serv_addr.sin_zero),8);
 if (connect(sockfd, (struct sockaddr *)&serv_addr, \
   sizeof(struct sockaddr)) == -1) {
perror("connect出错!");
exit(1);
}
 if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1) {
perror("recv出错!");
exit(1);
}
 buf[recvbytes] = '\0';
 printf("Received: %s",buf);
 close(sockfd);
}

威廉-丁 2008-05-14
  • 打赏
  • 举报
回复
1.楼主,注释掉就可以了 fcntl(tcpsock,F_SETFL,O_NONBLOCK);
2.非阻塞方式的连接要加判断。
以下程序在linux 2.4.2编译执行通过。
服务器端。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#define SERVPORT 3333 /*服务器监听端口号 */
#define BACKLOG 10 /* 最大同时连接请求数 */
main()
{
int sockfd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */
 struct sockaddr_in my_addr; /* 本机地址信息 */
 struct sockaddr_in remote_addr; /* 客户端地址信息 */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
  perror("socket创建出错!"); exit(1);
}
my_addr.sin_family=AF_INET;
 my_addr.sin_port=htons(SERVPORT);
 my_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
 if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1)
{
perror("bind出错!");
exit(1);
}
 if (listen(sockfd, BACKLOG) == -1)
{
perror("listen出错!");
exit(1);
}
while(1)
{
  sin_size = sizeof(struct sockaddr_in);
  if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr,?sin_size)) == -1)
{
perror("accept出错");
continue;
}
  printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));

  if (!fork())
{ /* 子进程代码段 */
   if (send(client_fd, "Hello, you are connected!\n", 26, 0) == -1)
   perror("send出错!");
close(client_fd);
exit(0);
}
   close(client_fd);
  }
 }
}

cceczjxy 2008-05-14
  • 打赏
  • 举报
回复
一般非阻塞方式的连接要这样判断

if ((state=connect(tcpsock, (struct sockaddr *) &tcp_seraddr, sizeof(tcp_seraddr))) == 0)
{
printf("%d\n",state);
perror("connect() failed");
exit(0);
}
if (errno != EINPROGRESS)
{
close(tcpsock);
perror("connect..2");
return -1;
}
printf("success\n");
fuqd273 2008-05-14
  • 打赏
  • 举报
回复
学习……
mymtom 2008-05-14
  • 打赏
  • 举报
回复
其实按楼主的要求,需要把这一行注释掉就可以了!
fcntl(tcpsock,F_SETFL,O_NONBLOCK);
lhtang 2008-05-14
  • 打赏
  • 举报
回复
你是非阻塞的套接字 所以返回码不一定是正确的 因为套接口没等连接成功就返回了 是正常的。。。
dayongxie 2008-05-14
  • 打赏
  • 举报
回复
man connect:

EINPROGRESS
The socket is non-blocking and the connection cannot be com-
pleted immediately. It is possible to select(2) or poll(2) for
completion by selecting the socket for writing. After select(2)
indicates writability, use getsockopt(2) to read the SO_ERROR
option at level SOL_SOCKET to determine whether connect() com-
pleted successfully (SO_ERROR is zero) or unsuccessfully
(SO_ERROR is one of the usual error codes listed here, explain-
ing the reason for the failure).
mymtom 2008-05-14
  • 打赏
  • 举报
回复
fcntl(tcpsock,F_SETFL,O_NONBLOCK);
就是说:
如果connect不能马上完成就返回EINPROGRESS
如果要用NONBLOCK,
参考一下Richard Stevans的代码:

#include "unp.h"

int
connect_nonb(int sockfd, const SA *saptr, socklen_t salen, int nsec)
{
int flags, n, error;
socklen_t len;
fd_set rset, wset;
struct timeval tval;

flags = Fcntl(sockfd, F_GETFL, 0);
Fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

error = 0;
if ( (n = connect(sockfd, saptr, salen)) < 0)
if (errno != EINPROGRESS)
return (-1);

/* Do whatever we want while the connect is taking place. */

if (n == 0)
goto done; /* connect completed immediately */

FD_ZERO(&rset);
FD_SET(sockfd, &rset);
wset = rset;
tval.tv_sec = nsec;
tval.tv_usec = 0;

if ( (n = Select(sockfd + 1, &rset, &wset, NULL,
nsec ? &tval : NULL)) == 0) {
close(sockfd); /* timeout */
errno = ETIMEDOUT;
return (-1);
}

if (FD_ISSET(sockfd, &rset) || FD_ISSET(sockfd, &wset)) {
len = sizeof(error);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
return (-1); /* Solaris pending error */
} else
err_quit("select error: sockfd not set");

done:
Fcntl(sockfd, F_SETFL, flags); /* restore file status flags */

if (error) {
close(sockfd); /* just in case */
errno = error;
return (-1);
}
return (0);
}
fuqd273 2008-05-14
  • 打赏
  • 举报
回复
另外,如果还有错,把errno和返回值打出来。
perror("connect() failed");
只是定位,排错用的信息不足。
fuqd273 2008-05-14
  • 打赏
  • 举报
回复
改个socket端口进行新的测试。

或者把unix/linux reboot一下。

reality 2008-05-14
  • 打赏
  • 举报
回复
close已增加,结果一样。
出错信息:connect() failed: operation now in progress

#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket() and bind() */
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h> /* for atoi() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#include <fcntl.h>
#define TCPCLIENTPORT 10000
#define BUFFERSIZE 256
int main()
{

struct sockaddr_in s_addr;
struct sockaddr_in c_addr;
int sock,tcpsock;
socklen_t addr_len;
int len,tcplen;
char buff[BUFFERSIZE],tcprecvbuff[BUFFERSIZE];

struct sockaddr_in tcp_seraddr;
char *SerIP = "192.168.1.115";

if ((tcpsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
perror("socket() failed");
exit(0);
}
/* Construct the server address structure */
fcntl(tcpsock,F_SETFL,O_NONBLOCK);

memset(&tcp_seraddr, 0, sizeof(tcp_seraddr)); /* Zero out structure */
tcp_seraddr.sin_family = AF_INET; /* Internet address family */
tcp_seraddr.sin_port = htons(TCPCLIENTPORT); /* Server port */
tcp_seraddr.sin_addr.s_addr = inet_addr(SerIP); /* Server IP address */

/* Establish the connection to the echo server */
if (connect(tcpsock, (struct sockaddr *) &tcp_seraddr, sizeof(tcp_seraddr)) < 0)
{
perror("connect() failed");
exit(0);
}
close(tcpsock);
return 0;
}

fuqd273 2008-05-14
  • 打赏
  • 举报
回复
close(2) is used to close a socket. shutdown(2) closes parts of a full
duplex socket connection.

你开了socket就没关掉。用close扫尾关掉再测试一下。

23,110

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧