23,114
社区成员
发帖
与我相关
我的任务
分享
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/select.h>
#include <errno.h>
#include <netinet/tcp.h>
#include <sys/sendfile.h>
#include <strings.h>
#include <fcntl.h>
#define SERV_PORT 8889 /* 服务器监听端口号 */
//设置socket连接为非阻塞模式
void setnonblocking(int sockfd)
{
int opts;
opts = fcntl(sockfd, F_GETFL);
if(opts < 0) {
perror("fcntl(F_GETFL)\n");
exit(1);
}
opts = (opts | O_NONBLOCK);
if(fcntl(sockfd, F_SETFL, opts) < 0) {
perror("fcntl(F_SETFL)\n");
exit(1);
}
}
int main(int argc, char *argv)
{
int i, maxi, maxfd, listenfd, connfd, sockfd;
int rtn = 0;
int nready, client[FD_SETSIZE];
ssize_t n;
fd_set rest, allrest;
socklen_t clilen;
char buf[128];
struct sockaddr_in cliaddr, servaddr;
memset(buf, 0, sizeof(buf));
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
rtn = bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
if (rtn)
{
printf("bind err!\n");
exit(-1);
}
listen(listenfd, 20);
maxfd = listenfd;
maxi = -1;
for (i = 0; i < FD_SETSIZE; i++)
{
client[i] = -1;
}
FD_ZERO(&allrest);
FD_SET(listenfd, &allrest); /* 告诉内核,我们需要对哪些描述字进行测试 */
for (; ;)
{
rest = allrest;
nready = select(maxfd+1, &rest, NULL, NULL, NULL);
if (FD_ISSET(listenfd, &rest)) /* 返回后, rest结构中的内容被重写,任何未就绪的描述字被置为0 */
{
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
//setnonblocking(connfd); //设置为非阻塞
printf("new socket accept, connfd = %d\n", connfd);
for (i=0; i < FD_SETSIZE; i++)
{
if (client[i] < 0)
{
client[i] = connfd;
break;
}
}
if (i == FD_SETSIZE)
return -1;
FD_SET(connfd, &allrest);
if (connfd > maxfd)
maxfd = connfd;
if (i > maxi)
maxi = i;
if (--nready <= 0)
{
continue;
}
}
for (i = 0; i <= maxi; i++)
{
if ((sockfd = client[i]) < 0)
continue;
if (FD_ISSET(sockfd, &rest))
{
/*接受来自客户端的信息*/
if ((n = Readline(sockfd, (char *)buf, sizeof(buf))) == 0)
{
close(sockfd);
FD_CLR(sockfd, &allrest);
client[i] = -1;
}
else if (n > 0)
{
/*处理信息,并发送给具体的服务进行业务逻辑处理*/
printf("form client : %s[%d]\n", buf, n);
strcat(buf, "_server");
/*返回客户端处理结果*/
writen(sockfd, buf, sizeof(buf));
}
else if (n == -1)
{
printf("%s\n",strerror(errno));
}
if (--nready <= 0)
break;
}
}
}
}
/*自定制的read函数*/
ssize_t Readline(int fd, void *buf, size_t num)
{
ssize_t res;
size_t n;
char *ptr;
n = num;
ptr = (char *)buf;
while (n > 0)
{
if ((res = read(fd, ptr, n)) == -1)
{
if (errno == EINTR) /*中断*/ //非阻塞应该考虑 errno == EWOULDBLOCK || errno == EAGAIN?
res = 0;
else if (errno == ECONNRESET)
return 0;
else
{
return -1;
}
}
else if (res == 0)
break;
ptr += res;
n -= res;
}
return (num - n);
}
/*自定制的write函数*/
ssize_t writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;
ptr = (char *)vptr;
nleft = n;
while (nleft > 0)
{
if ((nwritten = write(fd, ptr, nleft)) <= 0)
{
if (nwritten < 0 && errno == EINTR) //非阻塞应该考虑 errno == EWOULDBLOCK || errno == EAGAIN
{
nwritten = 0;
}
else
{ printf("%s\n",strerror(errno));
return -1;
}
}
nleft -= nwritten;
ptr += nwritten;
}
return n;
}
int main(int argc, char *argv[])
{
int server;
int maxfd = 0;
ssize_t n;
char buf[128];
struct sockaddr_in sin;
struct hostent *host;
int clientmsgtype;
server = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(SERVPORT);
sin.sin_addr.s_addr = inet_addr("192.168.159.132");
if (connect (server, (struct sockaddr*)&sin, sizeof(sin))<0)
{
printf("connect err\n");
exit(1);
}
buf[0] = 'a';
write (server, &buf, sizeof(buf));
if ((n = read(server, (char *)buf, sizeof(buf))) > 0)
{
printf("%s\n", buf);
}
return 0;
}