unix域套接字实现echo服务

来源:互联网 发布:遗传算法与神经网络 编辑:程序博客网 时间:2024/05/28 05:18

===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 0if(0 != Daemon())exit(1);#endifchar *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;}


原创粉丝点击