socket编程的细节问题

原创 2013年12月04日 09:03:39

What is the difference between AF_INET and PF_INET in socket programming?

In some documentation, you'll see mention of a mystical "PF_INET". This is a weird etherial beast that is rarely seen in nature, but I might as well clarify it a bit here. Once a long time ago, it was thought that maybe a address family (what the "AF" in "AF_INET" stands for) might support several protocols that were referenced by their protocol family (what the "PF" in "PF_INET" stands for).
That didn't happen. Oh well. So the correct thing to do is to use AF_INET in your struct sockaddr_in and PF_INET in your call to socket(). But practically speaking, you can use AF_INET everywhere. And, since that's what W. Richard Stevens does in his book, that's what I'll do here.

linux客户端Socket非阻塞connect编程

You have a non-blocking socket and you are calling connect() in it. Since connect() needs the 3-way handshake to happen (so a network roundtrip), it either blocks waiting for the SYN-ACK in blocking sockets, or gives you some indication that it hasn't succeded yet in non-blocking sockets. Normally, non-blocking sockets return EAGAIN/EWOULDBLOCK to tell you that they couldn't progress and you should try again: this is not exactly your case, connect() returns EAGAIN/EWOULDBLOCK when there are no free ephemeral ports to tell you that you should try again later; so there is another error for non-blocking connect: EINPROGRESS, which tells you that the operation is in progress and you should check its status later.

To check the status later, the socket will become ready for writability, so you can useselect()/poll()/... to test for that, after which you'll have to getsockopt(...SO_ERROR...)to get the success/failure status of your connect() operation.

int tcp_connect(const char *addr, int port, int timeout)
{
	int fd, error, tmp;
	unsigned int len;
	struct sockaddr_in sa_in;
	struct timeval tv;
	fd_set fds;

	if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
		return -1;
	bzero(&sa_in, sizeof(sa_in));
	sa_in.sin_family = AF_INET;
	sa_in.sin_port = htons(port);
	sa_in.sin_addr.s_addr = inet_addr(addr);
	set_nonblocking(fd, 1);
	PRINTF("Connect IP: %s PORT: %d(tcp_client)\n", addr, port, timeout);
	tmp = connect(fd, (struct sockaddr *)&sa_in, sizeof(sa_in));
	if (tmp < 0) {
		error = errno;
		if (error != EINTR && error != EINPROGRESS) {
			close(fd);
			PRINTF("Connect fail reason:%s(tcp_client)\n",
			    strerror(error));
			return -1;
		}
	}
	while (timeout > 0) {
		tv.tv_sec = 0;
		tv.tv_usec = 0;
		FD_ZERO(&fds);
		FD_SET(fd, &fds);
		tmp = select(fd + 1, NULL, &fds, NULL, &tv);
		if (tmp > 0) {
			len = sizeof(error);
			if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0
				|| error) {
				close(fd);
				PRINTF("Connect fail reason:%s(tcp_client)\n",
					strerror(error));
				return -1;
			}
			else {
				set_nonblocking(fd, 0);
				PRINTF("Connect ok, fd is %d\n", fd);
				return fd;
			}
		}
		else if (tmp < 0) {
			error = errno;
			if (error != EINTR && error != EINPROGRESS) {
				close(fd);
				PRINTF("Connect fail, reason:%s(tcp_client)\n",
					strerror(error));
				return -1;
			}
		}
		msleep(100);
		timeout -= 100;
	}
	close(fd);
	PRINTF("Connect timeout(tcp_client)\n");
	return -1;
}


相关文章推荐

linux socket编程细节

Q: 编写 TCP/SOCK_STREAM 服务程序时,SO_REUSEADDR到底什么意思? A: 这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用端口。如...
  • zxygww
  • zxygww
  • 2013年10月31日 14:39
  • 862

SOCKET编程的小细节和误区

1. UDP使用的误区, 一个socket, 存在两个线程, 同时调用sendto和recvfrom, 是可行的, (阻塞模式下已经通过测试), 同时存在多个线程调用sendto或recvfrom才是...
  • dfasri
  • dfasri
  • 2011年07月20日 09:38
  • 866

Linux socket 编程细节

Q: 编写 TCP/SOCK_STREAM 服务程序时,SO_REUSEADDR到底什么意思? A: 这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用端口。如...

Linux下的socket编程实践(十) 基本UDP编程细节

在我的这两篇博客中,简单介绍并实现了基于UDP(TCP)的windows(UNIX下流程基本一致)下的服务端和客户端的程序,本文继续探讨关于UDP编程的一些细节。 http://blog.csdn....
  • NK_test
  • NK_test
  • 2015年10月26日 23:54
  • 1985

java UDP编程中一些小细节问题

//接收端 import java.net.DatagramSocket; import java.net.DatagramPacket; public class UDPServerA...

PHP 编程一些及其细微的细节问题

/////////////////    Windows下,记事本会把“utf-8 编码,无 bom”的文件变成“带bom”,也就是给文件前加三个字节“EF BB BF”。因为好像记事本只能保存“带b...

Linux socket 网络编程常见问题总结

网络编程常见问题总结 串讲(一)  网络编程常见问题总结  6 I& I! E- x8 Z+ p- U- B   在网络程序中遇到的一些问题进行了总结, 这里主要针对的是我们常用的TCP sock...

iOS经典讲解之socket编程”粘包“问题

TCP/IP传输层有两个并列的协议:TCP和UDP。其中TCP(transport control protocol,传输控制协议)是面向连接的,提供高可靠性服务。UDP(user datagram ...

Java网络编程socket的半包,粘包与分包的问题

http://zhaohuiopensource.iteye.com/blog/1541270 首先看两个概念:  短连接:  连接->传输数据->关闭连接     HTTP是无状态的,浏览器...

关于宽字符(_UNICODE||UNICODE)和windows套接(socket)字编程问题

在VS05里使用WSABUF结构体来发送数据的时候会遇到unicode的问题,假如 CString str = L"oh no~"; WSABUF wsaBuf; int len =...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:socket编程的细节问题
举报原因:
原因补充:

(最多只允许输入30个字)