Esempio n. 1
0
void TcpServer::update(uint32_t diff)
{
    int res;
    while((res = accept(m_sock_fd, NULL, 0)) >= 0)
    {
        const int optval = 1;
        ioctl(res, FIONBIO, &optval);
        LOGD("Client connected: %d", res);
        m_clients.push_back(tcp_client(res));
        onClientAdded();
    }

    // disconnected clients must be removed from m_clients in this method and nowhere else
    int av;
    for(std::vector<tcp_client>::iterator itr = m_clients.begin(); itr != m_clients.end(); )
    {
        av = available((*itr).fd);
        if(av > 0)
        {
            read_client(*itr);
            ++itr;
        }
        else if(av < 0 || (av == 0 && recv((*itr).fd, NULL, 0, 0) == 0))
        {
            LOGD("Client disconnected: %d", (*itr).fd);
            ::close((*itr).fd);
            itr = m_clients.erase(itr);
            onClientRm();
        }
        else
            ++itr;
    }
}
Esempio n. 2
0
std::string httpclient::get(std::string url) {
  tcpclient tcp_client(this->host, this->port);
  std::string message = std::string("GET ") + url + " HTTP/1.1\n Host: " +
                        this->host + ":" + this->port + "\n\n";
  auto read_message = tcp_client.write_read_string(message);
  return read_message;
}
Esempio n. 3
0
int main( int argc, char **argv )
{
	SOCKET s;
	int rc;
	int len;
	char buf[ 120 ];

	INIT();
	s = tcp_client( argv[ 1 ], argv[ 2 ] );
	while ( fgets( buf, sizeof( buf ), stdin ) != NULL )
	{
		len = strlen( buf );
		rc = send( s, buf, len, 0 );
		if ( rc < 0 )
			error( 1, errno, "send failed" );
		rc = readline( s, buf, sizeof( buf ) );
		if ( rc < 0 )
			error( 1, errno, "readline failed" );
		else if ( rc == 0 )
			error( 1, 0, "server terminated\n" );
		else
			fputs( buf, stdout );
	}
	EXIT( 0 );
}
Esempio n. 4
0
int main(int argc,char *argv[])
{
    if(argc != 5)
    {
		printf("Incorrect format\n");
        printf("\n Usage: %s <listenportno> <ip of server> <connectportno> <protocol>\n",argv[0]);
        return 1;
    } 
    char *listenportno = argv[1];
    char *connectportno = argv[3];
    char *ip = argv[2];
    if(strcmp(argv[3],"udp")==0)
		isudpset = 1;
    else
	 	isudpset = 0;
    pid_t pid;
    pid = fork();
    if(pid == 0)
    {
		if(isudpset)
			udp_server(listenportno);
		else
    	    tcp_server(listenportno);
    }
    else if(pid > 0)
    {        
		if(isudpset)
			udp_client(ip,connectportno);
		else
        	tcp_client(ip,connectportno);
    }
    return 0;
}
Esempio n. 5
0
int main(int argc, char **argv)
{
    struct sockaddr_in peer;
    char *hostname;
    char *servicename;
    char *filename;
    int peerlen;
    const int on = 1;

    if (argc == 4) {
        hostname = argv[1];
        servicename = argv[2];
        filename = argv[3];
    } else {
        error(1, errno, "number of parametrs mismatch\n");
    }

    s = tcp_client(hostname, servicename);
    if (s < 0)
        error(1, errno, "error in tcp_client\n");

    signal(SIGURG, sig_urg);
    fcntl(s, F_SETOWN, getpid());

    client(s, &peer, filename);
    close_socket(s);
    printf("Counter OOB: %ld\n", count_data);
    exit(0);
}
Esempio n. 6
0
int Proxy_connect(Proxy *conn) 
{
  Node *rhdr = NULL, *rmsg = NULL;
  Node *imsg = NULL;
  bstring header = NULL;
  int rc = 0;

  assert_mem(conn);

  CryptState_init();

  // create the peer crypto we need
  conn->state = CryptState_create(conn->client.name, conn->client.key);
  check_err(conn->state, CRYPTO, "Failed to initialize cryptography subsystem.");
  conn->state->data = conn;

  log(INFO, "Connecting to %s:%s as %s expecting server named %s", 
      bdata(conn->host.host), bdata(conn->host.port),
      bdata(conn->client.name), bdata(conn->host.name));

  // connect to the hub
  conn->host.fd = tcp_client((char *)bdata(conn->host.host), (char *)bdata(conn->host.port));
  check_err(conn->host.fd >= 0, NET, "Failed to connect to Hub.");

  rmsg = readnodes(conn->host.fd, &rhdr);
  check_err(!rmsg && rhdr, PEER_ESTABLISH, "Incorrectly formatted initial message from Hub.");

  // generate first response
  imsg = CryptState_initiator_start(conn->state, rhdr, &header, Proxy_confirm_key);
  Node_destroy(rhdr); rhdr = NULL;
  check_err(imsg, PEER_ESTABLISH, "Failed to construct response to Hub's first message.");

  rc = write_header_node(conn->host.fd, header, imsg);
  Node_destroy(imsg); imsg = NULL;
  bdestroy(header); header = NULL;
  check_err(rc > 0, PEER_ESTABLISH, "Failed sending response to Hub's first message.");

  rmsg = readnodes(conn->host.fd, &rhdr);
  check_err(rmsg && rhdr, PEER_ESTABLISH, "Invalid response from hub.");
  header = Node_bstr(rhdr, 1); Node_destroy(rhdr); rhdr = NULL;

  rc = CryptState_initiator_process_response(conn->state, header, rmsg);
  check_err(rc, PEER_ESTABLISH, "Failed to process receiver 2nd message.");
  Node_destroy(rmsg); bdestroy(header); header = NULL; rmsg = NULL;

  imsg = CryptState_initiator_send_final(conn->state, &header);
  check_err(imsg, PEER_ESTABLISH, "Failed to generate final message.");

  rc = write_header_node(conn->host.fd, header, imsg);
  check_err(rc > 0, PEER_ESTABLISH, "Failed to write final message to hub.");

  check_err(Proxy_final_verify(conn), PEER_VERIFY, "Final verify of Hub info failed.");

  // remember, rc>0 is how we make sure that everything went ok during processing
  ensure(if(imsg) Node_destroy(imsg);
      if(rmsg) Node_destroy(rmsg);
      if(rhdr) Node_destroy(rhdr);
      if(header) bdestroy(header);
      return rc > 0);
}
Esempio n. 7
0
static void privop_pasv_get_data_sock(session_t *sess)
{
    unsigned short port = (unsigned short)priv_sock_get_int(sess->parent_fd);
    char ip[16] = {0};
    priv_sock_recv_buf(sess->parent_fd, ip, sizeof(ip));
    printf("privop_pasv_get_data_sock port=%u and ip=%s\n", port, ip);
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);

    int fd = tcp_client(20);
    if(fd == -1)
    {
        printf("aaaaaaaaaaaaaaaaaaa\n");
        priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_BAD);
        return;
    }
    socklen_t len = sizeof(struct sockaddr_in);;
    if(connect(fd, (struct sockaddr*)&addr, len) < 0)
    {
        printf("bbbbbbbbbbbbbbbbb\n");
        ERR_EXIT("ccccconect");
        close(fd);
        priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_BAD);
        ERR_EXIT("connect");
        return;
    }

    priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_OK);
    priv_sock_send_fd(sess->parent_fd, fd);
    close(fd);
}
Esempio n. 8
0
xnet_tcp_client_ptr xclient::connect_to(const xstring& host, xport_t port)
{
    xnet_tcp_client_ptr tcp_client(new xnet_tcp_client(io_service()));
    tcp_client->set_uuid(_X("{30201EA2-7AD5-46e8-91D6-7D3E878C8DC4}"));
    //tcp_client->set_handler_manager();
    tcp_client->connect_to(host, port);
    return tcp_client;
}
Esempio n. 9
0
int
main(int argc, char *argv[])
{
	pid_t child_pid, parent_pid;
	struct sockaddr_in sin;
	int listen_fd;
	u_short port;
	socklen_t len;

	listen_fd = socket(PF_INET, SOCK_STREAM, 0);
	if (listen_fd < 0)
		err(-1, "socket");

	/*
	 * We use the loopback, but let the kernel select a port for the
	 * server socket.
	 */
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_len = sizeof(sin);
	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

	if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
		err(-1, "bind");

	if (listen(listen_fd, -1) < 0)
		err(-1, "listen");

	/*
	 * Query the port so that the client can use it.
	 */
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_len = sizeof(sin);
	len = sizeof(sin);
	if (getsockname(listen_fd, (struct sockaddr *)&sin, &len) < 0)
		err(-1, "getsockname");
	port = sin.sin_port;
	printf("Using port %d\n", ntohs(port));

	if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
		err(-1, "signal");

	parent_pid = getpid();
	child_pid = fork();
	if (child_pid < 0)
		err(-1, "fork");
	if (child_pid == 0) {
		child_pid = getpid();
		tcp_server(parent_pid, listen_fd);
	} else
		tcp_client(child_pid, port);

	return (0);
}
Esempio n. 10
0
int main(int argc, char *argv[])
{
	
	if (argc == 1) {
		tcp_server();
	} 
	
	tcp_client(argv[1]);
		
	return 0;
}
Esempio n. 11
0
int main( int argc, char **argv )
{
	fd_set allfd;
	fd_set readfd;
	msg_t msg;
	struct timeval tv;
	SOCKET s;
	int rc;
	int heartbeats = 0;
	int cnt = sizeof( msg );

	INIT();
	s = tcp_client( argv[ 1 ], argv[ 2 ] );
	FD_ZERO( &allfd );
	FD_SET( s, &allfd );
	tv.tv_sec = T1;
	tv.tv_usec = 0;
	for ( ;; )
	{
		readfd = allfd;
		rc = select( s + 1, &readfd, NULL, NULL, &tv );
		if ( rc < 0 )
			error( 1, errno, "select failure" );
		if ( rc == 0 )		/* timed out */
		{
			if ( ++heartbeats > 3 )
				error( 1, 0, "connection dead\n" );
			error( 0, 0, "sending heartbeat #%d\n", heartbeats );
			msg.type = htonl( MSG_HEARTBEAT );
			rc = send( s, ( char * )&msg, sizeof( msg ), 0 );
			if ( rc < 0 )
				error( 1, errno, "send failure" );
			tv.tv_sec = T2;
			continue;
		}
		if ( !FD_ISSET( s, &readfd ) )
			error( 1, 0, "select returned invalid socket\n" );
		rc = recv( s, ( char * )&msg + sizeof( msg ) - cnt,
			cnt, 0 );
		if ( rc == 0 )
			error( 1, 0, "server terminated\n" );
		if ( rc < 0 )
			error( 1, errno, "recv failure" );
		heartbeats = 0;
		tv.tv_sec = T1;
		cnt -= rc;					/* in-line readn */
		if ( cnt > 0 )
			continue;
		cnt = sizeof( msg );

		/* process message */
	}
}
Esempio n. 12
0
File: app.c Progetto: rvba/minuit
void app_launch(t_app *app)
{
	if(app->off_screen)
	{
		//app_off_screen(app);
		if(app->client)
		{
			 tcp_client();
		}
		else if(app->slave)
		{
			 slave();
		}
		#ifdef HAVE_OSC
		else if(app->osc_server)
		{
			osc_server( app->osc_port);
		}
		else if(app->osc_client)
		{
			osc_client( app->osc_port);
		}
		#endif
		else
		{
			if( app->main_func)
			{
				app->main_func();
			}
		}
	}
	else
	{
		#ifdef HAVE_SDL
		sdl_mainloop( app);
		#else
		#if HAVE_GLUT
		glutMainLoop();
		#else
		if( app->x_func)
		{
			app->x_func( app->argc, app->argv, app->name);
		}
		else
		{
			printf("No X\n");
		}

		#endif
		
		#endif
	}
}
Esempio n. 13
0
int main(int argc, char ** argv) {
	if (argc != 3) {
		printf("Usage: client maxnprobes(max numer of probes of unreachable) secofgap(gao of two sequece heart beat packet)\n");
		return 0;
	}
	maxnprobes = atoi(argv[1]);
	secofgap = atoi(argv[2]);

	tcp_client();
	heartbeat_client();
	while (1) {}
	return 0;
}
Esempio n. 14
0
std::string httpclient::post(std::string url, std::string body) {
  logging log_obj("httpclient.log");
  tcpclient tcp_client(this->host, this->port);
  int body_length = body.length();
  std::string body_length_str = std::to_string(body_length - 1);
  std::string message = std::string("POST ") + url + " HTTP/1.1\n Host: " +
                        this->host + ":" + this->port + "\n" +
                        "User-agent: huyorg/0.0.1\n Accept: */*\nContent-Type: "
                        "application/json\n" +
                        "Content-Length: " + body_length_str + "\n\n" + body +
                        "\n";
  auto read_message = tcp_client.write_read_string(message);
  log_obj.write(read_message);
  return read_message;
}
Esempio n. 15
0
File: ipc.c Progetto: semibiotic/bee
int link_request(link_t * ld, char * host, int service)
{  int rc;

   rc = tcp_init(0);
   if (rc < 0) return (-1);

   rc = tcp_socket(0);
   if (rc < 0) return (-1);
   ld->fd = rc;
   
   rc = tcp_client(ld->fd, host, service);
   if (rc == (-1)) return (-1);

   return 0;
}
Esempio n. 16
0
int
main(int argc, char *argv[])
{
	pid_t child_pid, parent_pid;

	if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
		err(-1, "signal");

	parent_pid = getpid();
	child_pid = fork();
	if (child_pid < 0)
		err(-1, "fork");
	if (child_pid == 0) {
		child_pid = getpid();
		tcp_server(parent_pid);
		return (0);
	} else
		tcp_client(child_pid, 0);
	(void)kill(child_pid, SIGTERM);

	sleep(5);

	parent_pid = getpid();
	child_pid = fork();
	if (child_pid < 0)
		err(-1, "fork");
	if (child_pid == 0) {
		child_pid = getpid();
		tcp_server(parent_pid);
		return (0);
	} else
		tcp_client(child_pid, 1);
	(void)kill(child_pid, SIGTERM);

	return (0);
}
Esempio n. 17
0
tcp_client tcp_server::accept()
{
    struct sockaddr_in clientAddr;
    socklen_t cliLen = sizeof(clientAddr);

    int clientSocket = ::accept(_sock_fd, (struct sockaddr *)&clientAddr, &cliLen);
    if (clientSocket == -1 ) {
        throw socket_exception(system::error_code(errno));
    }

    end_point dest, src;
    dest.port = listen_port();
    src.ip = ::inet_ntoa(clientAddr.sin_addr);

    return tcp_client(clientSocket, src, dest);
}
Esempio n. 18
0
int main( int argc, char **argv )
{
	SOCKET s;
	int n;
	char buf[ 128 ];
	struct iovec iov[ 2 ];

	INIT();
	s = tcp_client( argv[ 1 ], argv[ 2 ] );
	iov[ 0 ].iov_base = ( char * )&n;
	iov[ 0 ].iov_len = sizeof( n );
	iov[ 1 ].iov_base = buf;
	while ( fgets( buf, sizeof( buf ), stdin ) != NULL )
	{
		iov[ 1 ].iov_len = strlen( buf );
		n = htonl( iov[ 1 ].iov_len );
		if ( writev( s, iov, 2 ) < 0 )
			error( 1, errno, "writev failure" );
	}
	EXIT( 0 );
}
Esempio n. 19
0
static void privop_pasv_get_data_sock(session_t *sess)
{
	/*
		socket
		bind 20
		connect
		*/
		// tcp_client(20);
		/*
	*/
	char ip[16] = {0};
	unsigned short port = (unsigned short)priv_sock_get_int(sess->parent_fd);
	priv_sock_recv_buf(sess->parent_fd, ip, sizeof(ip));
	
	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = inet_addr(ip);
	
	int fd = tcp_client(20);
	if (fd == -1) 
	{
		priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_BAD);
		return;
	}
	
	if (connect_timeout(fd, &addr, tunable_connect_timeout) < 0)
	{
		close(fd);
		priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_BAD);
		return;
	}
	
	priv_sock_send_result(sess->parent_fd, PRIV_SOCK_RESULT_OK);
	priv_sock_send_fd(sess->parent_fd, fd);
	close(fd);
}
Esempio n. 20
0
void main(int argc,char *argv[])
{
    char *list_port,*conn_port, *ip;
    pid_t pid;
    if(argc != 4)
    {
        printf("Plz give the correct arguments.\n");
        return;
    } 
    ip = argv[1];
    conn_port = argv[2];
    list_port= argv[3];
    pid = fork();
    if(pid == 0)
    {
        tcp_server(atoi(list_port));
    }
    else if(pid > 0)
    {        
       tcp_client(ip,atoi(conn_port));
    }
    
}
Esempio n. 21
0
int main(int argc, char *argv[]) {
  char proto, mode;
  unsigned int addr;
  unsigned short port;

  //read arguments (options)
  readargs(argc, argv, &proto, &mode, &addr, &port, "10001");

  if(mode == 's') {
    if(proto == 'u') {
      udp_server(port);
    } else {
      tcp_server(port);
    }
  } else {
    if(proto == 'u') {
      udp_client(addr, port, 0);
    } else {
      tcp_client(addr, port, 0);
    }
  }

  return 0;
}
Esempio n. 22
0
static void privop_port_get_data_sock(session_t *sess)
{
	unsigned short port = (unsigned short)priv_sock_get_int(sess->nobody_fd);
	char ip[20] = {0};
	priv_sock_recv_buf(sess->nobody_fd, ip, sizeof(ip));

	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = inet_addr(ip);

// 当多个客户端连接服务器时,可以同时有多个nobody进程bind 20端口+ip,因为此时客户端给出的端口是随机的,故
// 四元组还是能识别一个数据连接
// 当客户端位于NAT服务器之后使用PORT模式时,需要在NAT服务器上配置映射才能让服务器主动连接到客户端
// 所以采用的是标准固定的20端口,这样NAT服务器就不用维护很多的表目
	int fd = tcp_client(20);
	if (fd == -1)
	{
		priv_sock_send_result(sess->nobody_fd, PRIV_SOCK_RESULT_BAD);
		return;
	}

	if (connect_timeout(fd, &addr, tunable_connect_timeout) < 0)
	{
		close(fd);
		priv_sock_send_result(sess->nobody_fd, PRIV_SOCK_RESULT_BAD);
		return;
	}

	priv_sock_send_result(sess->nobody_fd, PRIV_SOCK_RESULT_OK);
	priv_sock_send_fd(sess->nobody_fd, fd);
	close(fd); //父进程必须close(fd),否则子进程关闭close(data_fd)的时候也不会发送FIN段。
	//因为通过unix域协议传递套接字等于是对方也打开套接字,而直接简单的赋值是没有这样的效果的。

}
Esempio n. 23
0
int nfs_mount(const char *pathname, const char *hostname,
	      uint32_t server, const char *rem_path, const char *path,
	      struct nfs_mount_data *data)
{
	struct client *clnt = NULL;
	struct sockaddr_in addr;
	char mounted = 0;
	int sock = -1;
	int ret = 0;
	int mountflags;

	if (get_ports(server, data) != 0)
		goto bail;

	dump_params(server, rem_path, data);

	if (data->flags & NFS_MOUNT_TCP)
		clnt = tcp_client(server, mount_port, CLI_RESVPORT);
	else
		clnt = udp_client(server, mount_port, CLI_RESVPORT);

	if (clnt == NULL)
		goto bail;

	if (data->flags & NFS_MOUNT_VER3)
		ret = mount_v3(rem_path, data, clnt);
	else
		ret = mount_v2(rem_path, data, clnt);

	if (ret == -1)
		goto bail;
	mounted = 1;

	if (data->flags & NFS_MOUNT_TCP)
		sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	else
		sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

	if (sock == -1) {
		perror("socket");
		goto bail;
	}

	if (bindresvport(sock, 0) == -1) {
		perror("bindresvport");
		goto bail;
	}

	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = server;
	addr.sin_port = htons(nfs_port);
	memcpy(&data->addr, &addr, sizeof(data->addr));

	strncpy(data->hostname, hostname, sizeof(data->hostname));

	data->fd = sock;

	mountflags = (data->flags & NFS_MOUNT_KLIBC_RONLY) ? MS_RDONLY : 0;
	data->flags = data->flags & NFS_MOUNT_FLAGMASK;
	ret = mount(pathname, path, "nfs", mountflags, data);

	if (ret == -1) {
		if (errno == ENODEV) {
			fprintf(stderr, "mount: the kernel lacks NFS v%d "
				"support\n",
				(data->flags & NFS_MOUNT_VER3) ? 3 : 2);
		} else {
			perror("mount");
		}
		goto bail;
	}

	dprintf("Mounted %s on %s\n", pathname, path);

	goto done;

bail:
	if (mounted) {
		if (data->flags & NFS_MOUNT_VER3)
			umount_v3(path, clnt);
		else
			umount_v2(path, clnt);
	}

	ret = -1;

done:
	if (clnt)
		client_free(clnt);

	if (sock != -1)
		close(sock);

	return ret;
}
Esempio n. 24
0
int
main(int argc, char *argv[])
{
	struct sockaddr_in sin;
	pid_t child_pid, parent_pid;
	int listen_fd;
	socklen_t len;
	u_short port;

	if (signal(SIGCHLD, SIG_IGN) == SIG_ERR)
		err(-1, "signal");

	/*
	 * Run the whole thing twice: once, with a short sleep in the client,
	 * so that we close before time wait runs out, and once with a long
	 * sleep so that the time wait terminates while the socket is open.
	 * We don't reuse listen sockets between runs.
	 */
	listen_fd = socket(PF_INET, SOCK_STREAM, 0);
	if (listen_fd < 0)
		err(-1, "socket");

	/*
	 * We use the loopback, but let the kernel select a port for the
	 * server socket.
	 */
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_len = sizeof(sin);
	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

	if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
		err(-1, "bind");

	if (listen(listen_fd, -1) < 0)
		err(-1, "listen");

	/*
	 * Query the port so that the client can use it.
	 */
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_len = sizeof(sin);
	len = sizeof(sin);
	if (getsockname(listen_fd, (struct sockaddr *)&sin, &len) < 0)
		err(-1, "getsockname");
	port = sin.sin_port;
	printf("Using port %d\n", ntohs(port));

	parent_pid = getpid();
	child_pid = fork();
	if (child_pid < 0)
		err(-1, "fork");
	if (child_pid == 0) {
		child_pid = getpid();
		tcp_server(child_pid, listen_fd);
		exit(0);
	} else
		tcp_client(parent_pid, port, 1);
	(void)kill(child_pid, SIGTERM);
	close(listen_fd);
	sleep(5);

	/*
	 * Start again, this time long sleep.
	 */
	listen_fd = socket(PF_INET, SOCK_STREAM, 0);
	if (listen_fd < 0)
		err(-1, "socket");

	/*
	 * We use the loopback, but let the kernel select a port for the
	 * server socket.
	 */
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_len = sizeof(sin);
	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

	if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
		err(-1, "bind");

	if (listen(listen_fd, -1) < 0)
		err(-1, "listen");

	/*
	 * Query the port so that the client can use it.
	 */
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_len = sizeof(sin);
	len = sizeof(sin);
	if (getsockname(listen_fd, (struct sockaddr *)&sin, &len) < 0)
		err(-1, "getsockname");
	port = sin.sin_port;
	printf("Using port %d\n", ntohs(port));

	parent_pid = getpid();
	child_pid = fork();
	if (child_pid < 0)
		err(-1, "fork");
	if (child_pid == 0) {
		child_pid = getpid();
		tcp_server(parent_pid, listen_fd);
	} else
		tcp_client(child_pid, port, 800);

	return (0);
}
int main( int argc, char* argv[] )
{
	if ( argc != 4 )
	{
		std::cout << "error parameters. usage: " << argv[0] << " ip port packetnum";
		return -1;
	}

    Log::init();

	int packetnum = atoi( argv[3] );

	if ( packetnum < 0 )
	{
		packetnum = 100;
	}

	socketstartup();
	SOCKET clientfd = tcp_client( argv[1], argv[2] );

	if ( !isvalidsock( clientfd ) )
	{
		Log::trace( "cannot connect server" );
		return -1;
	}

	char recvbuf[MAX_BUF_SIZE];

	int sendcount = 0;
	int recvcount = 0;
	int recverrorcount = 0;

	for ( ;; )
	{
		int recvn = recv( clientfd, recvbuf, sizeof( recvbuf ), 0 );

		if ( sizeof( recvbuf ) == recvn )
		{
			bool brecvwrite = true;
			for ( int i = 0; i < sizeof( recvbuf ); ++i )
			{
				if ( recvbuf[i] != 'A' )
				{
					brecvwrite = false;
					break;
				}
			}

			if ( brecvwrite )
			{
#ifdef H_OS_WINDOWS
                static DWORD tmLastRecvMsg = 0;
                DWORD tnow = GetTickCount();
                double fdiff = (double)( tnow - tmLastRecvMsg ) / 1000.0f;
                if ( fdiff > 2.0 )
                {
                    std::ostringstream log;
                    log << "recv a message from server, but it is too long, interval:" << fdiff << "s.";
                    Log::error( log.str() );
                }
                else
                {
                    Log::trace( "recv a message from server." );
                }
                tmLastRecvMsg = tnow;
#else
                Log::trace( "recv a message from server." );
#endif
				recvcount++;
			}
			else
			{
				Log::trace( "recv message, but the content is wrong." );
				recverrorcount++;
			}
		}
		else
		{
			static int errorcount = 0;

			if ( 10 == errorcount++ )
			{
				break;
			}
		}

        if ( recvcount == packetnum )
        {
            memset( recvbuf, 'q', sizeof(recvbuf) );
        }

		int sendn = 0;
		do
		{
			sendn = send( clientfd, recvbuf, sizeof( recvbuf ), 0 );

			if ( -1 == sendn )
			{
				static int errorcount = 0;

				if ( 10 == errorcount++ )
				{
					break;
				}

				std::cout << "send error. errno=" << getLastSocketError();
				msleep( 100 );
			}
			else
			{
				//Log::trace( "                      send a message to client." );
				sendcount++;
				break;
			}
		}
		while ( -1 == sendn );


        if ( recvcount == packetnum )
        {
            std::ostringstream log;
            log << "===========================================================";
            log << "\n\tRecv count=" << recvcount
                << "\n\tSend count=" << sendcount
                << "\n\tRecv error count=" << recverrorcount;
            log << "\n===========================================================";
            Log::trace( log.str() );

            CLOSE_SOCKET( clientfd );
            break;
        }
		
	} // end of send-recv for(;;)


	return 0;
}