本地套接字通信有两种方式:一种是tcp流程,一种是udp流程。
TCP localSocket流程:
- server端
/*
tcp的本地套接字服务器流程:
创建套接字 socket(AF_UNIX,SOCK_STREAM,0)
绑定 struct sockaddr_un &强转
侦听 listen
获得新连接 accept
循环通信 read-write
关闭文件描述符 close
*/
//本地socket通讯服务端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/un.h>
int main(){
//创建socket
int lfd = socket(AF_UNIX,SOCK_STREAM,0);//SOCK_STREAM:tcp流程
if(lfd<0){
perror("socket error");
return -1;
}
//删除socket文件,避免bind失败 (如果套接字存在,删除套接字)
unlink("./server.sock");
//绑定
struct sockaddr_un serv;
bzero(&serv,sizeof(serv));
serv.sun_family = AF_UNIX;
strcpy(serv.sun_path,"./server.sock");
int ret = bind(lfd,(struct sockaddr *)&serv,sizeof(serv));
if(ret<0){
perror("bind error");
return -1;
}
//监听
listen(lfd,10);
//接收新的链接-accept
struct sockaddr_un client;
bzero(&client,sizeof(client));
socklen_t len = sizeof(client);
int cfd = accept(lfd,(struct sockaddr*)&client,&len);
if(cfd<0){
perror("accept error");
return -1;
}
printf("cient->[%s]\n",client.sun_path);
int n;
char buf[1024];
while(1){
//读取数据
memset(buf,0x00,sizeof(buf));
n = read(cfd,buf,sizeof(buf));
if(n<=0){
printf("read error or client close ,n=[%d]\n",n);
break;
}
printf("n=[%d],buf=[%s]\n",n,buf);
//发送数据
write(cfd,buf,n);
}
//关闭套接字
close(lfd);
return 0;
}```
- client端:
```c
/*
tcp本地套接字客户端流程:
调用socket创建套接字
调用bind函数将socket文件描述和socket文件进行绑定.
不是必须的, 若无显示绑定会进行隐式绑定,但服务器不知道谁连接了.
调用connect函数连接服务端
循环通信read-write
关闭文件描述符 close
*/
//本地socket通信客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/un.h>
int main(){
//创建socket
int cfd = socket(AF_UNIX,SOCK_STREAM,0);//tcp流程
if(cfd<0){
perror("socket error");
return -1;
}
//删除socket文件,避免bind失败(如果套接字存在,删除套接字)
unlink("./client.sock");
//绑定
struct sockaddr_un client;
bzero(&client,sizeof(client));
client.sun_family= AF_UNIX;
strcpy(client.sun_path,"./client.sock");
int ret = bind(cfd,(struct sockaddr*)&client,sizeof(client));
if(ret<0){
perror("bind error");
return -1;
}
struct sockaddr_un serv;
bzero(&serv,sizeof(serv));
serv.sun_family = AF_UNIX;
strcpy(serv.sun_path,"./server.sock");
ret = connect(cfd,(struct sockaddr*)&serv,sizeof(serv));
if(ret<0){
perror("connect error");
return -1;
}
int n;
char buf[1024];
while(1){
memset(buf,0x00,sizeof(buf));
n = read(STDIN_FILENO,buf,sizeof(buf));
//发送数据
write(cfd,buf,n);
//读取数据
memset(buf,0x00,sizeof(buf));
n = read(cfd,buf,sizeof(buf));
if(n<=0){
printf("read error or client close ,n=[%d]",n);
break;
}
printf("n=[%d],buf=[%s]",n,buf);
}
close(cfd);
return 0;
}
UDP localSocket流程:
- server端:
/*
(1)创建UNIX域数据报套接字;socket(AF_LOCAL, SOCK_DGRAM, 0)
(2)填充本地信息结构体(服务器);struct sockaddr_un
(3)绑定本地地址(服务器的地址信息);bind( )
(4)接收客户端的数据;recvfrom( )
(5)发送数据给客户端;sendto( )
*/
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<sys/un.h>
#include<stdlib.h>
#define N 64
int main(int argc, const char *argv[])
{
int sockfd;
struct sockaddr_un serveraddr, clientaddr;
char buf[N];
socklen_t len = sizeof(clientaddr);
sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);//udp流程
if(sockfd < 0)
{
perror("fail to sockfd");
return -1;
}
//删除socket文件,避免bind失败(如果套接字存在,删除套接字)
unlink("mysocket");
serveraddr.sun_family = AF_LOCAL;
strcpy(serveraddr.sun_path, "mysocket");
unlink(serveraddr.sun_path);
if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
{
perror("fail to bind");
return -1;
}
while(1)
{
if(recvfrom(sockfd, buf, N, 0, (struct sockaddr*)&clientaddr, &len) < 0)
{
perror("fail to recvfrom");
return -1;
}
if(strncmp(buf, "quit", 4) == 0)
{
break;
}
buf[strlen(buf) - 1] = '\0';
printf("buf:%s\n", buf);
strcat(buf, "++++----");
if(sendto(sockfd, buf, N, 0, (struct sockaddr*)&clientaddr, sizeof(clientaddr)) < 0)
{
perror("fail to sendto");
return -1;
}
}
close(sockfd);
return 0;
}
- client端:
/*
客户端使用流程:
(1)创建UNIX域数据报套接字;socket(AF_LOCAL, SOCK_DGRAM, 0)
(2)填充本地信息结构体(服务器端和客户端);struct sockaddr_un
(3)绑定本地地址(客户端的地址信息);bind( )
(4)发送数据给服务器端;sendto( )
(5)接收服务器端的数据;recvfrom( )
*/
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/un.h>
#include<string.h>
#define N 64
int main(int argc, const char *argv[])
{
int sockfd;
char buf[N];
struct sockaddr_un serveraddr, clientaddr;
sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);//udp流程
if(sockfd < 0)
{
perror("fail to sockfd");
return -1;
}
//删除socket文件,避免bind失败(如果套接字存在,删除套接字)
unlink("mysocket");
serveraddr.sun_family = AF_LOCAL;
strcpy(serveraddr.sun_path, "mysocket");
clientaddr.sun_family = AF_LOCAL;
strcpy(clientaddr.sun_path, "socket");
unlink(clientaddr.sun_path);
if(bind(sockfd, (struct sockaddr*)&clientaddr, sizeof(clientaddr)) < 0)
{
perror("fail to bind");
return -1;
}
while(1)
{
printf("<client>");
fgets(buf, N, stdin);
if(sendto(sockfd, buf, N, 0, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
{
perror("fail to sendto");
return -1;
}
if(strncmp(buf, "quit", 4) == 0)
{
break;
}
if(recvfrom(sockfd, buf, N, 0, NULL, NULL) < 0)
{
perror("fail to recvfrom");
return -1;
}
printf("buf:%s\n", buf);
}
close(sockfd);
return 0;
}