linux网络编程多进程并发,linux网络编程多进程并发服务器

服务器端代码

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT 1234

#define MAXSIZE1024

struct ARG

{

int connfd;

struct sockaddr_in clientAddr;

};

void savedata(char *recvbuf, int len, char *cli_data)

{

static int index = 0;

int i = 0;

while (i < len-1)

{

cli_data[index++] = recvbuf[i];

i++;

}

cli_data[index] = '\0';

}

static int clientProcess(int connfd, struct sockaddr_in clientSock)

{

int num = 0;

int i = 0;

char recvBuf[MAXSIZE];

char sendBuf[MAXSIZE];

char clientName[MAXSIZE];

char cli_data[MAXSIZE];

struct timeval val;

fd_set fd;

int ret;

val.tv_sec = 0;

val.tv_usec = 0;

num = recv(connfd, clientName, MAXSIZE, 0);

if (num < 0)

{

printf("recv clientName message from client!\n");

return -1;

}

clientName[strlen(clientName)-1] = '\0';

printf("You got's a connection from %s, client name is %s\n",

inet_ntoa(clientSock.sin_addr), clientName);

while (1)

{

FD_ZERO(&fd);

FD_SET(connfd, &fd);

ret = select(FD_SETSIZE, &fd, NULL, NULL, &val);

num = recv(connfd, recvBuf, MAXSIZE, 0);

if (num == 0)

{

printf("Client(%s) closed connection\nUser's data:%s\n",clientName, cli_data);

close(connfd);

return -1;

}

recvBuf[strlen(recvBuf)-1] = '\0';

printf("received client (%s) message :%s\n", clientName, recvBuf);

//保存接收到的信息

savedata(recvBuf, num, cli_data);

//将接收到的客户端数据加密返回给客户端

for (i=0; i

{

if ((recvBuf[i]>='a' && recvBuf[i]<='z') || (recvBuf[i]>='A' && recvBuf[i]<='Z'))

{

recvBuf[i] = recvBuf[i] + 3;

if ((recvBuf[i]>'Z' && recvBuf[i]'z'))

{

recvBuf[i] = recvBuf[i] -26;

}

}

sendBuf[i] = recvBuf[i];

}

sendBuf[num-1] = '\0';

send(connfd, sendBuf, MAXSIZE, 0);

memset(sendBuf, 0, MAXSIZE);

memset(recvBuf, 0, MAXSIZE);

}

close(connfd);

return 1;

}

void *funThread(void *arg)

{

struct ARG *info;

info = (struct ARG *)arg;

clientProcess(info->connfd, info->clientAddr);

free(arg);

arg = NULL;

pthread_detach(pthread_self());

pthread_exit(NULL);

}

int main(int argc, char **argv)

{

int listenfd, connfd;

pthread_t pid_t;

struct ARG *arg;

struct sockaddr_in serveraddr;

struct sockaddr_in clientaddr;

socklen_t len;

listenfd = socket(AF_INET, SOCK_STREAM, 0);

if (listenfd < 0)

{

printf("Creating socket failed!\n");

return -1;

}

int opt = SO_REUSEADDR;

setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

bzero(&serveraddr, sizeof(serveraddr));

serveraddr.sin_family = AF_INET;

serveraddr.sin_port = htons(PORT);

serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

if (bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)

{

printf("bind fails!\n");

return -1;

}

if (listen(listenfd, 5) < 0)

{

printf("listen fails!\n");

return -1;

}

len = sizeof(clientaddr);

for (;;)

{

connfd = accept(listenfd, (struct sockaddr *)&clientaddr, &len);

if (connfd < 0)

{

printf("accept fails!\n");

return -1;

}

arg = (struct ARG *)malloc(sizeof(struct ARG));

if (arg == NULL)

{

printf("malloc memory fails!\n");

return -1;

}

memset(arg, 0, sizeof(struct ARG));

arg->connfd = connfd;

memcpy((void *)&arg->clientAddr, &clientaddr, sizeof(clientaddr));

//处理客户端信息

if (pthread_create(&pid_t, NULL, funThread, (void *)arg) < 0)

{

printf("Create thread fails!\n");

return -1;

}

}

close(listenfd);

}

客户端代码:

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT1234

#define MAXSIZE 1024

static int clientProcess(FILE *fp, int connfd)

{

char readLine[MAXSIZE];

char recvLine[MAXSIZE];

int num;

printf("connect to server success!\n");

printf("Input client's name:");

if (fgets(readLine, MAXSIZE, fp) == NULL)

{

printf("fgets fails!\n");

return -1;

}

send(connfd, readLine, MAXSIZE, 0);

while (fgets(readLine, MAXSIZE, fp) != NULL)

{

if (strncmp(readLine, "quit", strlen("quit")) == 0)

{

fflush(stdin);

exit(-1);

}

send(connfd, readLine, strlen(readLine), 0);

num = recv(connfd, recvLine, MAXSIZE, 0);

if (num < 0)

{

printf("received fails!\n");

return -1;

}

recvLine[num-1] = '\0';

printf("Server message:%s\n", recvLine);

}

return 1;

}

int main(int argc, char **argv)

{

int sockfd;

struct sockaddr_in serverSock;

struct hostent *he;

if (argc != 2)

{

printf("Usage: %s \n", argv[0]);

return -1;

}

he = gethostbyname(argv[1]);

if (he == NULL)

{

printf("gethostbyname fails!\n");

return -1;

}

sockfd = socket(AF_INET, SOCK_STREAM, 0);

if (sockfd < 0)

{

printf("Create socket fails!\n");

return -1;

}

bzero(&serverSock, sizeof serverSock);

serverSock.sin_family = AF_INET;

serverSock.sin_port = htons(PORT);

serverSock.sin_addr = *((struct in_addr *)he->h_addr);

if (connect(sockfd, (struct sockaddr *)&serverSock, sizeof serverSock) < 0)

{

printf("connect fails!\n");

return -1;

}

clientProcess(stdin, sockfd);

close(sockfd);

return 1;

}编译运行。

首先运行服务器程序,然后打开两个客户端终端并连接上服务器程序。如下图所示:

服务器运行情况:

1db4ae06dd9ab4afa2f87a10fa1f602c.png

客户端1运行情况:

1ef1adf93b5f31b2bd44636c3ec80d52.png

客户端2运行情况:

2e43ae3d3cc770ca4cc7207b141c5e97.png

仔细看服务端运行情况就能看到问题,当客户端1退出后,执行

savedata(recvBuf, num, cli_data);的信息能够打印出来,当客户端2退出时,结果却不打印保存的信息。这是为什么?这就是非线程安全的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值