1.socket函数
用于创建一个socket,返回其句柄
#include
#include
int socket(int domin, int type, int protoclo)
domin:
AF_INET:使用TCP或者UDP来传输,用IPV4的地址
AF_INET6:使用IPV6的地址
AF_UNIX:本地协议,使用在linux和UNIX系统上,一般都是当客户端和服务器在统一台机器上的时候和斯用
type:
SOCK_STREAM:按照顺序的,可靠的,数据完整地基于字节流的连接,使用TCP来连接
SOCK_DGRAM:这个协议是无连接的,固定长度的传输调用,是不可靠的,使用UDP来进行连接
protocol:
0表示使用默认协议
返回值:
成功返回socket的句柄,失败返回-1,且设置errno
2. bind函数
用于绑定socket和ip/端口,以进行服务监听
INADDR_ANY用于监听本机的所有IP地址
#include
#include
int bind(int socket, const struct sockaddr* addr, socklen_t addrlen)
socket: socket句柄
addr:构建出的IP地址和端口号
addrlen:sizeof(addr)的长度
返回值:成功返回0,失败返回-1,并设置errno
3.listen函数
用于设置等待建立连接的队列长度
#include
#include
int listen(int sockfd, int backlog)
sockfd:socket的句柄
backlog:linux系统中,队列等待建立3次握手队列长度
注意:如何查看系统限制的backlog数
cat /proc/sys/net/ipv4/tcp_max_syn_backlog
如何修改系统限制的backlog的大小:
vim etc/sysctl.conf
添加
net.core.somaxconn = 2048
net.ipv4.tcp_max_syn_backlog = 2048
然后执行sysctl -p
使用sysctl -a 查询
4.accept函数
三次握手完成之后,服务器用accept函数接受连接,如果服务器调用accept时还没有客户端的连接请求,就会阻塞等待。
#include
#include
int accept(int sockfd, (struct sockaddr*)addr, socklen* addrlen)
sockfd: 当前服务器的sock句柄
addr:传出参数,接入的客户端的地址。可以为null,表示不在乎客户端的地址
addrlen:传出参数的大小
返回:客户端的sock句柄
5.connect函数
用于客户端连接到服务器
#include
#include
int connect(int sockdf, (const struct sockaddr*)addr, socklen len)
同bind函数
6.代码示例
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 256
#define SERVER_PORT 666
int main(int argc, char* argv[])
{
int server_sock;
int client_sock;
socklen_t len;
char buf[BUFFER_SIZE];
struct sockaddr_in server_sock_addr;
struct sockaddr_in client_sock_addr;
if((server_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("socket error!\n");
return -1;
}
bzero(&server_sock_addr, sizeof(server_sock_addr));
bzero(&client_sock_addr, sizeof(client_sock_addr));
server_sock_addr.sin_family = AF_INET;
server_sock_addr.sin_addr.s_addr = INADDR_ANY;
server_sock_addr.sin_port = htons(SERVER_PORT);
if((bind(server_sock, (struct sockaddr*)&server_sock_addr, sizeof(server_sock_addr))) == -1)
{
printf("bind error!\n");
return -1;
}
if(listen(server_sock,128) == -1)
{
printf("listen error!\n");
return -1;
}
printf("等待客户端接入\n");
while(1)
{
if((client_sock = accept(server_sock, (struct sockaddr*)&client_sock_addr, &len)) == -1)
{
printf("accept error!\n");
return -1;
}
char client_ip[256];
printf("client ip[%s], port[%d]\n",
inet_ntop(AF_INET, &client_sock_addr.sin_addr.s_addr, client_ip, sizeof(client_ip)),
ntohs(client_sock_addr.sin_port));
int l;
if((l = read(client_sock,buf,BUFFER_SIZE-1)) <= 0)
{
printf("read error!\n");
return -1;
}
buf[l] = '\0';
if(write(client_sock, buf, l) < 0)
{
printf("write error!\n");
return -1;
}
close(client_sock);
}
return 0;
}
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char* argv[])
{
if(argc != 4)
{
printf("param num error!\n");
return -1;
}
struct sockaddr_in server_sock_addr;
bzero(&server_sock_addr,sizeof(server_sock_addr));
server_sock_addr.sin_family = AF_INET;
inet_pton(AF_INET, argv[1], &server_sock_addr.sin_addr);
server_sock_addr.sin_port = htons(atoi(argv[2]));
printf("dst ip[%s %d], port[%s %d]\n",
argv[1], server_sock_addr.sin_addr.s_addr,
argv[2], server_sock_addr.sin_port);
int server_sock;
if((server_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("socket error!\n");
return -1;
}
socklen_t socklen = sizeof(server_sock_addr);
if(connect(server_sock, (struct sockaddr*)&server_sock_addr, socklen) == -1)
{
printf("connect error!\n");
return -1;
}
if(write(server_sock, argv[3], strlen(argv[3])) <= 0)
{
printf("write error!\n");
}
char buf[256];
int len;
if((len = read(server_sock, buf, 255)) <= 0)
{
printf("read error!\n");
}
buf[len] = '\0';
printf("read %s\n",buf);
return 0;
}