===server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stddef.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/fcntl.h>
int BindAndListen(char *psUnixDomainPath, int nRequests)
{
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
return -1;
unlink(psUnixDomainPath);
int nReuseSoAddr = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &nReuseSoAddr, sizeof(nReuseSoAddr));
struct sockaddr_un tUnixName;
memset(&tUnixName, 0, sizeof(tUnixName));
tUnixName.sun_family = AF_UNIX;
strcpy(tUnixName.sun_path, psUnixDomainPath);
int len = offsetof(struct sockaddr_un, sun_path) + strlen(psUnixDomainPath);
if(0 > bind(fd, (struct sockaddr *)&tUnixName, len))
{
close(fd);
return -1;
}
if(0 > listen(fd, nRequests) )
{
close(fd);
return -1;
}
fcntl(fd, F_SETFL, O_ASYNC);
return fd;
}
int Select2Read(int nfd, int nTvSec, int nTvUsec)
{
if(nfd > 0 )
{
struct timeval tvTimeout;
fd_set fdSet;
FD_ZERO(&fdSet);
FD_SET(nfd, &fdSet);
tvTimeout.tv_sec = nTvSec;
tvTimeout.tv_usec = nTvUsec;
return select(nfd + 1, &fdSet, NULL, NULL, &tvTimeout);
}
return nfd;
}
void *EchoServer(void *argv)
{
pthread_t t = pthread_self();
pthread_detach(t);
int nSockFd = *(int *)argv;
printf("%lu, server start, socket = %d\r\n", t, nSockFd);
while (1)
{
if(Select2Read(nSockFd, 120, 0) <= 0)
{
printf("%lu, timeout or select error, socket = %d\r\n", t, nSockFd);
break;
}
char sBuffer[1024] = { 0 };
int nReadBytes = read(nSockFd, sBuffer, 1024);
printf("%lu, read %d bytes\r\n", t, nReadBytes);
if(nReadBytes < 0)
{
switch(errno)
{
case EINTR:
{
//todo:
break;
}
case ECONNRESET:
{
//todo:
break;
}
default:break;
}
printf("%lu, read fail, return %d, errno %d, socket %d\r\n", t, nReadBytes, errno, nSockFd);
continue;
}
int nWriteBytes = write(nSockFd, sBuffer, strlen(sBuffer));
printf("%lu, write %d bytes\r\n", t, nWriteBytes);
if(nWriteBytes < 0 )
{
switch(errno)
{
case EINTR:
{
//todo:
break;
}
case ECONNRESET:
{
//todo:
break;
}
default:break;
}
printf("%lu, write fail, return %d, errno %d, socket %d\r\n", t, nWriteBytes, errno, nSockFd);
continue;
}
}
printf("%lu, server exit, socket = %d\r\n", t, nSockFd);
close(nSockFd);
free(argv);
return (void *)0;
}
int Daemon()
{
pid_t PID;
if((PID = fork()) < 0)
{
perror("create daemon fail\r\n");
return -1;
}
else if (PID != 0)
{
return -2;
}
setsid();
signal(SIGCHLD, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
int fd = open("/dev/null", O_RDONLY);
dup2(fd, 0);
close(fd);
fd = open("/dev/null", O_WRONLY);
dup2(fd, 1);
dup2(fd, 2);
close(fd);
return 0;
}
int main(void)
{
#if 0
if(0 != Daemon())
exit(1);
#endif
char *psUnixDomainPath = "/tmp/us";
int fd = BindAndListen(psUnixDomainPath, 50);
printf("fd = %d\r\n", fd);
if(fd <= 0)
return -1;
while(1)
{
struct sockaddr tClientAddr;
int nSockLen = sizeof(tClientAddr);
int *nAcceptFd = (int *)calloc(1, sizeof(int));
*nAcceptFd = accept(fd, (struct sockaddr *)&tClientAddr, (socklen_t *)&nSockLen);
printf("accept fd = %d\r\n", *nAcceptFd);
if(-1 == *nAcceptFd)
{
free(nAcceptFd);
usleep(100000);
continue;
}
pthread_t pthService = 0;
if (0 != pthread_create(&pthService, NULL, EchoServer, nAcceptFd))
{
printf("pthread create fail\r\n");
close(*nAcceptFd);
free(nAcceptFd);
usleep(100000);
}
}
return EXIT_SUCCESS;
}
===client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <unistd.h>
#include <errno.h>
#include <sys/un.h>
#include <sys/socket.h>
int Connect(char *psPath)
{
if ( NULL == psPath || '\0' == *psPath )
return -1;
int nSockfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (nSockfd < 0)
return -1;
int nReuseSoAddr = 1;
setsockopt(nSockfd, SOL_SOCKET, SO_REUSEADDR, &nReuseSoAddr, sizeof(nReuseSoAddr));
struct sockaddr_un tSockUn;
memset(&tSockUn, 0x0, sizeof(tSockUn));
tSockUn.sun_family = AF_UNIX;
strncpy(tSockUn.sun_path, psPath, 107);
int len = offsetof(struct sockaddr_un, sun_path) + strlen(psPath);
if(connect(nSockfd, (struct sockaddr *)&tSockUn, len) < 0)
return -1;
return nSockfd;
}
int main(void)
{
char *psUnixDomainPath = "/tmp/us";
int fd = Connect(psUnixDomainPath);
printf("fd = %d\r\n", fd);
if( fd <= 0 )
return 0;
while(1)
{
printf("put message:\r\n");
char sBuffer[1024] = { 0 };
gets(sBuffer);
int nWriteLen = write(fd, sBuffer, strlen(sBuffer));
printf("write %d bytes, errno %d\r\n", nWriteLen, errno);
if (nWriteLen <= 0)
{
switch (errno)
{
case EINTR:
{
//todo:
break;
}
default: break;
}
continue;
}
char sReadBuffer[1024] = { 0 };
int nReadLen = read(fd, sReadBuffer, 1024);
printf("read %d bytes, errno %d\r\n", nReadLen, errno);
if (nReadLen <= 0)
{
switch (errno)
{
case EINTR:
{
//todo:
break;
}
default: break;
}
continue;
}
printf("get message:[%s]\r\n", sReadBuffer);
}
close(fd);
return EXIT_SUCCESS;
}
本文介绍了一个基于Unix域套接字实现的简单客户端-服务器通信程序。服务器端使用多线程方式处理客户端请求,并实现了超时重试机制。客户端通过输入消息发送到服务器,并接收回显的消息。
3659

被折叠的 条评论
为什么被折叠?



