计算机网络 套接字 是什么,网络套接字和本地套接字

socket网络编程

0e7bc7a9af23d9c4bcef396df69b7b37.png

1:网络套接字

创建套接字,返回值就是套接字的文件描述符

int socket(int domain,int type,int protocol);//创建一个套接字

//domain(域):确定通信的特性,如AF_INET--IPv4,AF_INET6--IPv6,AF_UNIX--UNIX

//type:确定套接字类型,如SOCKET_STREAM(流式套接字),SOCKET_SEQPACKET(报文传递)

//protocol:确定type下的特定协议,一般用0,表示默认协议,TCP,UDP

将套接字与地址关联

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

//sockfd:由socket返回的套接字的文件描述符

//addr:地址信息

//len:地址长度

设置监听

int listen(int sockfd, int backlog);//socfd套接字文件描述符,backlog,正在请求建立连接的最大数量

等待连接

int accept(int sockfd, void *addr, int *addrlen);

//sockfd:socket()创建的文件描述符

//addr,用来接收客户端传来的地址等基本信息

//addrlen:addr长度

客户端请求建立连接

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

//sockfd:客户端的socket()创建的文件描述符

//serv_addr:保存这目的端口和ip等服务器基本信息

//addrlen:serv_addr长度

断开连接(二选一)

close(sockfd);//关闭套接字,进入四次挥手阶段,只是断开当前进程和socket的连接

int shutdown(int sockfd, int how);//端口所有socket连接

2:本地套接字

UNIX域套接字

UNIX域套接字用于同一台计算机上运行的进程之间的通信。他的执行效率更高,仅仅是复制数据,并不执行协议处理,不需要添加和删除网络报头,不需要计算校验和等

只支持流式和数据报两种接口,服务是可靠的,不会丢失报文也不会出错,

创建套接字

这里不用UDP和TCP

int socket(int domain,int type,int protocol);//创建一个套接字

//domain(域):AF_UNIX--UNIX

//type:确定套接字类型,如SOCKET_STREAM(流式套接字),SOCKET_SEQPACKET(报文传递)(其实这个参数并没有用。这里只是占了个位置)

//protocol:确定type下的特定协议

bind 绑定定函数:

unlink(path)//确保之前path文件不存在,bind会创建该文件。。。如果存在这个文件不unlink,bind会失败

int bind(int socket, const struct sockaddr *address, size_t address_len);

sockaddr 此处是

struct sockaddr_un {

sa_family_t sun_family; //AF_UNIX

char sun_path[108]; //表示本地文件路径名,(可以为相对路径也可以为绝对路径) 分为两种一个是普通路径名(linux文件路径)必须以NULL('\0')结尾,

}

客户端请求建立连接

int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

//sockfd:客户端的socket()创建的文件描述符

//serv_addr:保存服务器sun_path

//addrlen:serv_addr长度

服务器

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "wrap.h"

#define SERV_ADDR "serv.socket"

int main(void)

{

int lfd, cfd, len, size, i;

struct sockaddr_un servaddr, cliaddr;

char buf[4096];

lfd = Socket(AF_UNIX, SOCK_STREAM, 0);

bzero(&servaddr, sizeof(servaddr));

servaddr.sun_family = AF_UNIX;

strcpy(servaddr.sun_path,SERV_ADDR);

len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path); /* servaddr total len */

unlink(SERV_ADDR); /* 确保bind之前serv.sock文件不存在,bind会创建该文件 */

Bind(lfd, (struct sockaddr *)&servaddr, len); /* 参3不能是sizeof(servaddr) */

Listen(lfd, 20);

printf("Accept ...\n");

while (1) {

len = sizeof(cliaddr);

cfd = Accept(lfd, (struct sockaddr *)&cliaddr, (socklen_t *)&len);

len -= offsetof(struct sockaddr_un, sun_path); /* 得到文件名的长度 */

cliaddr.sun_path[len] = '\0'; /* 确保打印时,没有乱码出现 */

printf("client bind filename %s\n", cliaddr.sun_path);

while ((size = read(cfd, buf, sizeof(buf))) > 0) {

for (i = 0; i < size; i++)

buf[i] = toupper(buf[i]);

write(cfd, buf, size);

}

close(cfd);

}

close(lfd);

return 0;

}

客户端

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "wrap.h"

#define SERV_ADDR "serv.socket"

#define CLIE_ADDR "clie.socket"

int main(void)

{

int cfd, len;

struct sockaddr_un servaddr, cliaddr;

char buf[4096];

cfd = Socket(AF_UNIX, SOCK_STREAM, 0);

bzero(&cliaddr, sizeof(cliaddr));

cliaddr.sun_family = AF_UNIX;

strcpy(cliaddr.sun_path,CLIE_ADDR);

len = offsetof(struct sockaddr_un, sun_path) + strlen(cliaddr.sun_path); /* 计算客户端地址结构有效长度 */

unlink(CLIE_ADDR);

Bind(cfd, (struct sockaddr *)&cliaddr, len); /* 客户端也需要bind, 不能依赖自动绑定*/

bzero(&servaddr, sizeof(servaddr)); /* 构造server 地址 */

servaddr.sun_family = AF_UNIX;

strcpy(servaddr.sun_path,SERV_ADDR);

len = offsetof(struct sockaddr_un, sun_path) + strlen(servaddr.sun_path); /* 计算服务器端地址结构有效长度 */

Connect(cfd, (struct sockaddr *)&servaddr, len);

while (fgets(buf, sizeof(buf), stdin) != NULL) {

write(cfd, buf, strlen(buf));

len = read(cfd, buf, sizeof(buf));

write(STDOUT_FILENO, buf, len);

}

close(cfd);

return 0;

}

//注:clie.socket ,serv.socket是socket伪文件,相当于管道,实际不占空间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值