一、UDP服务端
socket bind //绑定 recvfrom
ssize_t recvfrom(int sockfd, socket的fd
void *buf, 保存数据的一块空间的地址
size_t len, 这块空间的大小
int flags, 0 默认的接收方式 --- 阻塞方式
struct sockaddr *src_addr, 用来保存发送方的地址信息
socklen_t *addrlen ); 表示发送方实际的地址信息大小
返回值:成功 返回接收到的字节数 ,失败 -1
int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
功能:如果该函数在服务器端调用,则表示将参数1相关的文件描述符文件与参数2 指定的接口地址关联,用于从该接口接受数据。
如果该函数在客户端调用,则表示要将数据从参数1所在的描述符中取出并从参数2所在的接口设备上发送出去。
sockfd 之前通过socket函数创建的文件描述符,套接字id
my_addr 是物理接口的结构体指针。表示该接口的信息
注意:如果是客户端,则该函数可以省略,由默认接口发送数据。
int main(int argc, const char *argv[])
{
int fd = socket(AF_INET,SOCK_DGRAM,0);
if (fd < 0)
{
perror("socket fail");
return -1;
}
printf("fd = %d\n",fd);
struct sockaddr_in seraddr;
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = inet_addr("192.168.147.1");
if(bind(fd, (struct sockaddr *)&seraddr,sizeof(seraddr)) < 0)
{
perror("bind fail");
return -1;
}
struct sockaddr_in srcaddr;
socklen_t addrlen = sizeof(srcaddr);
char buf[1024];
while(1)
{
recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&srcaddr, &addrlen);
printf("---------------------------\n");
printf("IP = %s\n", inet_ntoa(srcaddr.sin_addr));
printf("post = %d\n", ntohs(srcaddr.sin_port));
printf("buf = %s\n", buf);
printf("---------------------------\n");
}
return 0;
实现一个UDP的回发:
二、TCPc/s模型
1.TCP客户端
建立连接 : 1.socket 2. bind //可选 3.connect ....
通信过程 :1.read 2.write 3.close
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:该函数固定有客户端使用,表示从当前主机向目标机发起链接请求。
参数:sockfd 本地socket创建的套接子id
addr 远程目标主机的地址信息。
addrlen: 参数2的长度。
返回值:成功 0,失败 -1;
int fd = socket(AF_INET,SOCK_STREAM,0);
if(fd < 0)
{
perror("socket fail");
return -1;
}
struct sockaddr_in seraddr;
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = inet_addr("192.168.159.130");
if(connect(fd,(const struct sockaddr *)&seraddr
,sizeof(seraddr)) < 0)
{
perror("connect fail");
}
2.TCP服务器
建立连接: 1.socket 2.bind 3.listen客户端的连接请求
4.accept ---这一步完成之后 连接就建立好了,之后就可以收发数据 .....
通信过程:1.read 2.write 3.close
int listen(int sockfd, int backlog);
函数功能:将套接字文件描述符从主动转为被动文件描述符,然后用于被动监听客户端的连接
函数返回值:成功返回0,失败返回-1, errno被设置
参数:sockfd
表示socket创建的套接字文件描述符
backlog
指定队列的容量
int listen_fd = socket(AF_INET,SOCK_STREAM,0);
if(listen_fd < 0)
{
handle_error("socket fail");
}
struct sockaddr_in seraddr;
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = inet_addr("192.168.159.130");
if(bind(listen_fd,(const struct sockaddr *)&seraddr
,sizeof(seraddr)) < 0)
{
handle_error("bind fail");
}
if(listen(listen_fd, 5) < 0)
{
handle_error("listen fail");
}
int connfd = accept(listen_fd, NULL, NULL);
if(connfd < 0)
{
handle_error("accept fail");
}
printf("connfd = %d\n", connfd);
tcp如何建立连接--------tcp三次握手
断开连接 tcp --------四次回收
实现一个tcp的回发: