socket 学习笔记

#include <sys/socket.h>

---------------------------------------------------------------------------------

1. int socket(int domain, int type, int protocol)

socket: return fd

domain: AF_INET(IPv4), AF_INET6(IPv6)

type: SOCK_DGRAM(udp), SOCK_STREAM(tcp), SOCK_RAM(ip)

protocol: 0(usually)

---------------------------------------------------------------------------------

2. int shutdown(int sockfd, int how)

how: SHUT_RD(read end) SHUT_RDWR(read end)

---------------------------------------------------------------------------------

3. network/host byte order

network: (TCP/IP: big-endian)

host:    (little-endian: x86, x86-64, linux, FreeBSD, )

#include <arpa/inet.h> or #include <netinet/in.h> (old)

htonl: host to network long (32bit)

htons: host to network short(16bit)

ntohl: network to host long (32bit)

ntohs: network to host short (16bit)

---------------------------------------------------------------------------------

4. socket address format

#include <netinet/in.h>

struct sockaddr {

sa_family-t sa_family;

char        sa_data[];

...

};

struct sockaddr_in {

sa_family_t sin_family;

in_port_t   sin_port;

struct in_addr sin_addr;

};

struct in_addr {

in_addr_t s_addr;

};

example:

struct sockaddr_in addr;

socklen_t addrlen = sizeof(struct sockaddr_in);

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = inet_addr("127.0.0.1");

addr.sin_port = htons(dtls_local_port);

connect(socket_fd, (struct sockaddr*)&addr, addrlen);

---------------------------------------------------------------------------------

5. bind (tcp/udp server端都需要bind)

int bind(int sockfd, const struct sockaddr *addr, socklen_t len);

1) 端口号必须大于1024,否则需要超级用户权限

2) 只有server需要bind, 客户端套接字bind没什么意义

3) 如果调用connect/listen,但没有bind,系统会选一个地扯将其bind到socket

int initserver(int type, const struct sockaddr *addr, socklen_t alen, int qlen)

{

int fd;

int err = 0;

if((fd = socket(addr->sa_family, type, 0)) <0)

return -1;

if(bind(fd, addr, alen) < 0) {

err = errno;

goto errout;

}

if(type == SOCK_STREAM || type == SOCK_SEQPACKET) {

if(listen(fd, qlen) < 0) {

err = errno;

goto errout;

}

}

return fd;

errout:

close(fd);

errno = err;

return -1;

}

---------------------------------------------------------------------------------

6.connect 面向连接的socket要用connect建立连接,无连接socket不是必须,但也可使用

***函数connect还可以用于无连接的网络服务(SOCK_DGRAM),如果在SOCK_DGRAM套接字上调用connect,

所有发送报文的目标地址设为connect调用中所指定的地址,这样每次传送报文时就不需要提供地址,

另外仅能接收来自指定地址的报文。

1) int connect(int sockfd, const struct sockaddr *addr, socklen_t len);

example:

#define MAXSLEEP 128

int connect_retry(int sockfd, const struct sockaddr *addr, socklen_t alen)

{

int nsec;

for(nsec=1; nsec <= MAXSLEEP; nsec <<= 1) {

if(connect(sockfd, addr, alen) == 0){

return 0; //connection accecpt

}

if(nsec <= MAXSLEEP/2)

sleep(nsec);

}

return(-1);

}

2) int listen(int sockfd, int backlog)

backlog: 表示该进程所要入队的连接请求数量

server调用listen宣告可以接受连接请求

3) accept

int accept(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict len);

server调用accept接受连接,如果没有连接请求到来,accept会阻塞直到一个请求到来。

如果sockfd是非阻塞模式,accept会return -1

accept返回一个fd,这个fd与sockfd套接字类型和地址族相同,原套接字继续保持listen

---------------------------------------------------------------------------------

9. send/receive data

0) read/write data from fd

1)ssize_t send(int sockfd, const void *buf, size_t nbyts, int flags);

使用send时套接字必须已经连接, 可忽略目的地址,或者在connect时设计目的地址

2)ssize_t sendto(int sockfd, const void *buf, size_t nbyts, int flags,

const struct sockaddr *destaddr, socklen-t destlen);

对于无连接的socket,可用sendto

3)ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);

可以指定多重缓冲区传输数据

01)ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);

面向连接

02) ssize_t recvfrom(int sockfd, void *restrict buf, size_t len, int flags,

struct sockaddr *restrict addr, socklen_t *restrict addrlen);

可用于无连接socket, 如果addr为空,recvfrom等同于recv

03) ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

---------------------------------------------------------------------------------

10. socket option

int setsockopt(int sockfd, int level, int option, const void *val, socklen_t len);

int getsockopt(int sockfd, int level, int option, const void *val, socklen_t * restrict lenp);

---------------------------------------------------------------------------------

11.异步

fcntl(fd, F_SETFL, O_NONBLOCK);

1)select

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

缺点:

1). nfds有限制,最大只能是1024

2). 知道有事件到来,还要遍历到底是哪个fd触发的

3).不能动态的修改fdset, 或者关闭某个socket

4)、需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大

优点:(select如此的老,我们还需要它吗?)

1). 更好的兼容老的系统

2). select 计算超时可以达到纳秒精度,而poll, epoll只能达到毫秒的精度。client/server用不着这么高,但嵌入式系统用的着。

事实上,如果你写一个不超过200个socket程序,select和poll, epool性能上没啥区别。

2)poll

int poll(struct pollfd *fds,nfds_t nfds, int timeout);

缺点:

1). 知道有事件到来,还要遍历到底是哪个fd触发的

2).不能动态的修改fdset, 或者关闭某个socket

优点:

1)没有fd个数限制

使用场景:

1)多平台支持,不仅仅是linux,你又不想使用libevent

2)不超过1000个sockets

3)超过1000个socket,但是socket都是short-lived的

4)Your application is not designed the way that it changes the events while another thread is waiting for them

3)epool   (epoll is Linux only)

int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);

1)Your application runs a thread poll which handles many network connections by a handful of threads.

单线程应用使用epool得不偿失,不比pool好

2)至少1000个以上的socket,socket

3)epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著

提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听

的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO

事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,

减少epoll_wait/epoll_pwait的调用,提高应用程序效率。

时间: 2025-01-14 03:46:45

socket 学习笔记的相关文章

C++ Socket 学习笔记

Socket学习笔记 以下均为整理,做参考之用. IP Address IP地址是指互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),是IP Address的缩写.IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异. IP地址被用来给Internet上的电脑一个编号.大家日常见到的情况是每台联网的PC上都需要有IP地址,才能正常通信.我们可以把"个人电脑"比作"

JAVA Socket学习笔记20140618

2014-06-18  23.59 http://blog.csdn.net/kongxx/article/details/7288896 http://blog.csdn.net/wwww1988600/article/details/8923927 http://blog.csdn.net/xunianchong/article/details/16358077 http://blog.csdn.net/wwww1988600/article/details/8924081 http://w

C# Socket学习笔记二

小记:昨天咱们已经了解了Socket的通信原理,可是点对点的一次通信并不是我们想要的,那么今天那我们就继续学习异步通信,简单来说就是服务器端和客户端可以进行多次 互发信息的通信而不用担心通道会关闭.在介绍异步通信时,客户端和服务器端的连接和上面介绍的同步通信建立连接的方式是一样的,只是接收和发送数据的方式改变了! 1.什么是异步通信? 异步:客户端请求之后,不必等到服务器回应之后就可以发送下一条请求,并行运行. 2.同步与异步的区别? 同步:我叫你吃饭,你若暂时有事情我就一直在那等,不干别的事情

C# Socket学习笔记一

小记:刚接触网络编程觉得网络是个神奇的东西,所以对它就很有兴趣,想了解下网络是如何进行进行数据传输的,那么开始第一天的学习吧!ReadyGo!!! 首先我们要了解一下几点内容: 1.网络中进程之间如何通信? 2.Socket是什么? 3.socket的基本操作 3.1.socket()函数 3.2.bind()函数 3.3.listen().connect()函数 3.4.accept()函数 3.5.read().write()函数等 3.6.close()函数 4.socket中TCP的三次

socket学习笔记——实现收发文件(Windows)

记录下来,供自己学习! server.c 1 #define _CRT_SECURE_NO_DEPRECATE 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <WinSock2.h> 6 #define BUF_SIZE 1024 7 char buf[BUF_SIZE], message[BUF_SIZE], file_name[BUF_SIZE];

Socket学习笔记

80端口是为HTTP(HyperText Transport Protocol)即超文本传输协议开放的,此为上网冲浪使用次数最多的协议,主要用于WWW(World Wide Web)即万维网传输信息的协议.可以通过HTTP地址(即常说的"网址")加":80"来访问网站,因为浏览网页服务默认的端口号都是80,因此只需输入网址即可,不用输入":80"了. 查询百度服务器IP地址:在cmd中输入ping www.baidu.com 什么是Buffere

Socket学习笔记(一)

1.socket介绍 我们知道两个进程如果需要进行通讯最基本的一个前提能能够唯一的标示一个进程,在本地进程通讯中我们可以使用PID来唯一标示一个进程,但PID只在本地唯一,网络中的两个进程PID冲突几率很大,这时候我们需要另辟它径了,我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示网络中的一个进程. 能够唯一标示网络中的进程后,它们就可以利用socket进行通信了. 什么是socket呢?我们经常把sock

socket学习笔记——select函数的使用(windows)

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <winsock2.h> 5 6 #define BUF_SIZE 1024 7 void error_handling(char* message); 8 9 int main(int argc, char* argv[]) 10 { 11 WSADATA wsadata; 12 SOCKET hServS

socket学习笔记——select与epoll函数的使用(linux)

select.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <arpa/inet.h> 6 #include <sys/socket.h> 7 #include <sys/time.h> 8 #include <sys/socket.h> 9 10 #defi