//----------------------------------------------------
//AUTHOR: lanyang123456
//DATE: 2014-10-30
//---------------------------------------------------
server:
/*
IPC
socket AF_UNIX
server
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <string>
#define UNIX_DOMAIN "/tmp/UNIX.domain"
#define QUEUE_LEN 5
using namespace std;
struct message {
int id;
string strmsg;
};
int main(void)
{
socklen_t clt_addr_len;
int listen_fd;
int com_fd;
int ret;
int i;
char recv_buf[1024];
socklen_t len;
struct sockaddr_un client_addr;
struct sockaddr_un server_addr;
struct message req;
listen_fd = socket(PF_UNIX, SOCK_STREAM, 0);
if(listen_fd < 0)
{
perror("cannot create communication socket");
return -1;
}
//set server addr
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, UNIX_DOMAIN, sizeof(server_addr.sun_path) - 1);
unlink(UNIX_DOMAIN);
//bind sockfd & addr
ret = bind(listen_fd, (struct sockaddr*)&server_addr,sizeof(server_addr));
if(ret == -1)
{
perror("cannot bind server socket");
close(listen_fd);
unlink(UNIX_DOMAIN);
return -1;
}
//listen sockfd
ret = listen(listen_fd, 1);
if(ret==-1)
{
perror("cannot listen the client connect request");
close(listen_fd);
unlink(UNIX_DOMAIN);
return -1;
}
//have connect request use accept
len = sizeof(client_addr);
com_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &len);
if(com_fd < 0)
{
perror("cannot accept client connect request");
close(listen_fd);
unlink(UNIX_DOMAIN);
return -1;
}
//read and printf sent client info
printf("-------accetpt client connect--------\n");
ret = read(com_fd, &req, sizeof(req));//req
if (ret <= 0)
{
printf("write error(%d) %s\n", errno, strerror(errno));
close(com_fd);
close(listen_fd);
unlink(UNIX_DOMAIN);
return -1;
}
printf("read client request.\n");
printf("strmsg.size() = %d\n",req.strmsg.size());
int msg_len = req.strmsg.size();
memset(recv_buf,0,1024);
ret = read(com_fd, recv_buf, msg_len);//body
if (ret <= 0)
{
printf("write error(%d) %s\n", errno, strerror(errno));
close(com_fd);
close(listen_fd);
unlink(UNIX_DOMAIN);
return -1;
}
req.strmsg.append(recv_buf, msg_len);
printf("Message from client : id: %d body: %s\n", req.id, req.strmsg.c_str());
close(com_fd);
close(listen_fd);
unlink(UNIX_DOMAIN);
return 0;
}
client:
/*
IPC
socket AF_UNIX
client
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <string>
#define UNIX_DOMAIN "/tmp/UNIX.domain"
using namespace std;
struct message {
int id;
string strmsg;
};
int main(void)
{
int connect_fd;
int ret;
char msg_body[1024];
int i;
static struct sockaddr_un server_addr;
struct message request;
//creat unix socket
connect_fd=socket(AF_UNIX, SOCK_STREAM, 0);
if(connect_fd<0)
{
perror("cannot create communication socket");
return 1;
}
server_addr.sun_family = AF_UNIX;
strcpy(server_addr.sun_path, UNIX_DOMAIN);
//connect server
ret=connect(connect_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if(ret==-1)
{
perror("cannot connect to the server");
close(connect_fd);
return 1;
}
memset(msg_body, 0, 1024);
strcpy(msg_body, "message from client");
request.id = 101;
request.strmsg.append(msg_body, strlen(msg_body));
ret = write(connect_fd, &request, sizeof(request));//request
if (ret <= 0)
{
printf("write error(%d) %s\n", errno, strerror(errno));
close(connect_fd);
return -1;
}
ret = write(connect_fd, msg_body, sizeof(msg_body));//body
if (ret <= 0)
{
printf("write error(%d) %s\n", errno, strerror(errno));
close(connect_fd);
return -1;
}
close(connect_fd);
return 0;
}
<span style="font-size:14px;">
</span>
$ g++ -o server server.cpp
$ g++ -o client client.cpp
./server
./client
server:
-------accetpt client connect--------
read client request.
Segmentation fault (core dumped)
分析:
从client接收string对象(假设为c),然后接收拷贝放到server端string对象(假设为s)中,server端string对象s相关地址是c对象中的地址;在server使用s对象引用地址,就存在内存越界问题(Segmentation fault)。
这是要深刻注意的!