linux多线程服务器

linux多线程服务器

这次的服务器包括了TCP多线程服务器,还包括了UDP的多线程服务器开发,这里主要说明下创建UDP和TCP流程,比如函数的使用方法,我也就简单介绍一下,大家自己查阅资料,当然也可以使用linux下的命令:man来查询,比较方便的。

UDP多线程:支持多客户端连接,当然也支持双方自由发送和接收数据。

TCP多线程:支持多客户端连接,当然也支持双方自由发送和接收数据。

UDP服务器:具体详细我就不一一列举了,大家可以参考我的CSDN博客:https://blog.csdn.net/Travelerwz/article/details/82084468

,相信大家一定遇到这样的文艺,就是要么是服务端收,要么是客户端只能发,这里,我给出一段代码,供大家参考!!

cli:

#include

#include

#include

#include

#include

#include

#define BUFFER 1024

#define PORT 8888

#define ERROR_EXIT(m) \

do \

{\

perror(m);\

exit(1);\

}while(0)

int main()

{

int len = 0;

char buf[BUFFER];

int recv = -1;

int res = -1;

struct sockaddr_in ser;

bzero(&ser,sizeof(ser));

ser.sin_family = AF_INET;

ser.sin_port = htons(PORT);

ser.sin_addr.s_addr = htonl(INADDR_ANY);

int socketfd = -1;

//建立socket

socketfd = socket(AF_INET,SOCK_DGRAM,0);

if(socketfd

{

ERROR_EXIT("socket");

}

len = sizeof(struct sockaddr);

while(1)

{

printf("waiting---->\n");

char recv_buf[512];

char send_buf[512];

if(NULL != fgets(recv_buf,sizeof(recv_buf),stdin))

{

res = sendto(socketfd,recv_buf,strlen(recv_buf),0,(struct sockaddr*)&ser,sizeof(struct sockaddr));

if(res

ERROR_EXIT("recvfrom");

else

printf("send data:%s\n",recv_buf);

}

res = recvfrom(socketfd,send_buf,strlen(send_buf),0,(struct sockaddr*)&ser,&len);

if(res

{

ERROR_EXIT("recvfrom");

}

else

{

printf("recv from ser :%s\n",send_buf);

}

}

close(socketfd);

return 0;

}

ser:

#include

#include /* See NOTES */

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define BUFFER 1024

#define PORT 8888

#define ERROR_EXIT(m) \

do \

{\

perror(m);\

exit(1);\

}while(0)

int main()

{

int len = 0;

int res = -1;

int cli_len = 0;

char send_buf[BUFFER];

int recv = -1;

struct sockaddr_in ser,cli;

bzero(&ser,sizeof(ser));

ser.sin_family = AF_INET;

ser.sin_port = htons(PORT);

ser.sin_addr.s_addr = htonl(INADDR_ANY);

int socketfd = -1;

//建立socket

socketfd = socket(AF_INET,SOCK_DGRAM,0);

if(socketfd

{

ERROR_EXIT("socket");

}

int on = 1;

int ret = -1;

ret = setsockopt( socketfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );

if(ret

{

ERROR_EXIT("setsockopt");

}

len = sizeof(struct sockaddr);

int b = -1;

b = bind(socketfd,(const struct sockaddr*)&ser,len);

if(b

{

ERROR_EXIT("bind");

}

//printf("IP:%s,port %d\n",SERVER_IP,PORT);

cli_len = sizeof(cli);

while(1)

{

printf(" server is waiting:\n");

char recv_send_buf[BUFFER];

char send_buf[BUFFER];

res = recvfrom(socketfd,recv_send_buf,sizeof(recv_send_buf),0,(struct sockaddr*)&cli,&cli_len);

if(res

{

ERROR_EXIT("recvfrom");

}

else

{

printf("from client data:%s\n",recv_send_buf);

}

if(NULL != fgets(send_buf,sizeof(send_buf),stdin))

{

res = sendto(socketfd,send_buf,sizeof(send_buf),0,(struct sockaddr*)&cli,cli_len);

if(res

{

ERROR_EXIT("sendto");

}

else

{

printf("sendto client:%s\n",send_buf);

}

}

}

close(socketfd);

return 0;

}

这个是我们平时创建的单线程的代码,接下来,给大家看一个多线程的代码:

cli:

#include

#include

#include

#include

#include

#include

#include

#define MAX_BUF_SIZE 1024

struct sockaddr_in srvaddr,clientaddr;

int sockfd,port,addrlen;

char s_msg[MAX_BUF_SIZE];

char receive[MAX_BUF_SIZE];

char bye[MAX_BUF_SIZE] = "bye\n";

void send_msg(void);//Ï̺߳¯Êý£¬·¢ÏûÏ¢

int main(int argc, char *argv[])

{

pthread_t pt_send = 0;

int ret;

//bye="bye\n";

if (argc!=3) {

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

return -1;

}

//convert port number

if ((port=atoi(argv[2]))

printf("port error\n");

return -1;

}

//create client udp socket

sockfd=socket(AF_INET,SOCK_DGRAM,0);

if(sockfd==-1){

printf("Socket create error\n");

return -1;

}

//assign server's sock address

addrlen=sizeof(struct sockaddr_in);

memset(&srvaddr, 0, sizeof(srvaddr));

srvaddr.sin_family=AF_INET;

srvaddr.sin_port=htons(port);

//convert IP address

if(inet_aton(argv[1],&srvaddr.sin_addr)

printf("IP error\n");

close(sockfd);

return -1;

}

printf("input bye to end CLIENT\n");

ret = pthread_create (&pt_send, NULL, (void *)send_msg, NULL);

if (ret != 0)

printf("pthread send_msg creat error\n");

while(1)

{

memset(receive,0, MAX_BUF_SIZE);

//receive message from remote server and print it

recvfrom(sockfd, receive, MAX_BUF_SIZE, MSG_DONTWAIT, (struct sockaddr *)(&clientaddr), &addrlen);

if (receive[0] != '\0' )

fprintf(stdout, "Receive message from server: %s", receive);

if (strcmp(receive,bye) == 0)

{

//printf("end session\n");

break;

}

}

//close socket

pthread_join (pt_send, NULL);

close(sockfd);

return 0;

}

void send_msg(void)

{

while(1)

{

memset(s_msg, 0, MAX_BUF_SIZE);

//get message from standard input

fgets(s_msg, MAX_BUF_SIZE, stdin);

//send message to remote server and print it

sendto(sockfd,s_msg,strlen(s_msg),MSG_DONTWAIT,(struct sockaddr *)(&srvaddr),addrlen);

printf("Client input message: %s", s_msg);

if (strcmp(s_msg, bye) == 0)

{

printf("end session\n");

break;

}

}

}

ser:

#include

#include

#include

#include

#include

#include

#define MAX_MSG_SIZE 1024

#define SERVER_PORT 3000

char s_msg[MAX_MSG_SIZE];//发消息

char receive[MAX_MSG_SIZE];//收消息

char bye[MAX_MSG_SIZE]="bye\n";

struct sockaddr_in srvaddr,clientaddr;

int sockfd,addrlen;

void send_msg(void);//线程函数,发消息

int main()

{

pthread_t pt_send = 0;

int ret;

sockfd=socket(AF_INET,SOCK_DGRAM,0);

if(sockfd==-1)//套接字描述符

{

printf("Socket create error\n");

return -1;

}

//assign server's sock address

memset(&srvaddr, 0, sizeof(srvaddr));

addrlen=sizeof(srvaddr);

srvaddr.sin_family=AF_INET;

srvaddr.sin_port=htons(SERVER_PORT);

if(inet_aton("127.0.0.1",&srvaddr.sin_addr)==-1)

{

printf("addr convert error\n");

close(sockfd);

return -1;

}

//srvaddr.sin_addr.s_addr=htonl(INADDR_ANY);

//bind IP address and port

if(bind(sockfd,(struct sockaddr *)&srvaddr,addrlen)==-1)

{

printf("bind error\n");

close(sockfd);

return -1;

}

printf("input bye to end SERVER\n");

ret = pthread_create (&pt_send, NULL, (void *)send_msg, NULL);

if (ret != 0)

printf("pthread send_msg creat error\n");

while(1)

{

memset(receive, 0, MAX_MSG_SIZE);

recvfrom(sockfd, receive, MAX_MSG_SIZE, 0, (struct sockaddr *)(&clientaddr), &addrlen);//非阻塞

if (receive[0] != '\0' )

fprintf(stdout, "Receive message from client: %s", receive);

if (strcmp(receive,bye) == 0)

break;

}

//while收消息,显示到标准输出,发消息,从标准如入写

//close socket

pthread_join (pt_send, NULL);

close(sockfd);

return 0;

}

void send_msg(void)

{

while(1)

{

memset(s_msg, 0, MAX_MSG_SIZE);

//get message from standard input

fgets(s_msg, MAX_MSG_SIZE, stdin);

//send message to client

sendto(sockfd,s_msg,strlen(s_msg),0,(struct sockaddr *)(&clientaddr),addrlen);

printf("Server input message: %s", s_msg);

if (strcmp(s_msg, bye) == 0)

{

printf("end session\n");

break;

}

}

}

接下来,我们看看TCP的代码,由于代码很容易理解,我就不一一解释了,不懂得可以私聊我。

cli:

#include

#include

#include

#include

#include

#include

#include

#define PORT 8080

#define MAX_NUM 128

#define ERROR(m) \

do \

{ \

perror(m); \

exit(0); \

}while(0)

int Socket()

{

int fd = 0;

fd = socket(AF_INET,SOCK_STREAM,0);

if(fd

{

ERROR("socket");

}

return fd;

}

int main()

{

int sockfd = -1;

int res = -1;

char recvbuf[MAX_NUM];

char sendbuf[MAX_NUM];

int num = 10;

pthread_t tid;

struct sockaddr_in cliaddr;

memset(&cliaddr,0,sizeof(cliaddr));

cliaddr.sin_family = AF_INET;

////IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址

cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);

cliaddr.sin_port = htons(PORT);

//创建套接字

sockfd = Socket();

int len = sizeof(cliaddr);

res = connect(sockfd,(struct sockaddr*)&cliaddr,len);

if(res

{

ERROR("connect");

}

printf("--------\n");

void* Write(void *arg)

{

while(1)

{

memset(sendbuf,0,MAX_NUM);

fgets(sendbuf,MAX_NUM,stdin);

res = send(sockfd,sendbuf,MAX_NUM,MSG_DONTWAIT);

printf("send:%s\n",sendbuf);

}

}

pthread_create(&tid,NULL,Write,NULL);

while(1)

{

res = recv(sockfd,recvbuf,MAX_NUM,MSG_DONTWAIT);

if(res > 0)

{

printf("recv:%s\n",recvbuf);

}

}

pthread_join(tid,NULL);

close(sockfd);

return 0;

}

ser:

#include

#include

#include

#include

#include

#include

#include

#include

#define PORT 8080

#define MAX_NUM 128

#define ERROR(m) \

do \

{ \

perror(m); \

exit(0); \

}while(0)

char recvbuf[MAX_NUM];

char sendbuf[MAX_NUM];

int res = -1;

int sockfd = -1;

int connect_fd = -1;

int Socket()

{

int fd = 0;

fd = socket(AF_INET,SOCK_STREAM,0);

if(fd

{

ERROR("socket");

}

return fd;

}

void Listen(int fd,int num)

{

int res = -1;

res = listen(fd,num);

if(res

{

ERROR("listen");

}

return ;

}

int main()

{

pthread_t tid,tid2;

int num = 10;

struct sockaddr_in seraddr;

memset(&seraddr,0,sizeof(seraddr));

seraddr.sin_family = AF_INET;

////IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址

seraddr.sin_addr.s_addr = htonl(INADDR_ANY);

seraddr.sin_port = htons(PORT);

//创建套接字

sockfd = Socket();

//端口复用

int opt = 1;

if(setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR, (const void *) &opt, sizeof(opt)))

{

ERROR("setsockopt");

}

//绑定

if(bind(sockfd,(struct sockaddr*)&seraddr,sizeof(seraddr))

{

ERROR("bind");

}

//监听

Listen(sockfd,num);

//读

void *Recv(void *arg)

{

while(1)

{

memset(recvbuf, 0, MAX_NUM);

res = recv(connect_fd,recvbuf,MAX_NUM,MSG_DONTWAIT);

if(res >= 0)

{

printf("recv:%s\n",recvbuf);

}

}

}

//写

void *Write(void *arg)

{

while(1)

{

memset(sendbuf,0,MAX_NUM);

fgets(sendbuf,MAX_NUM,stdin);

res = send(connect_fd,sendbuf,MAX_NUM,0);

printf("send:%s\n",sendbuf);

}

}

//等待客户端连接

printf("waiting client coming:\n");

int len = sizeof(seraddr);

while(1)

{

connect_fd = accept(sockfd,(struct sockaddr*)&seraddr,&len);

if(connect_fd

{

ERROR("accept");

}

printf("--------\n");

//创建线程

pthread_create(&tid,NULL,Write,NULL);

pthread_create(&tid2,NULL,Recv,NULL);

pthread_join(tid,NULL);

pthread_join(tid2,NULL);

}

close(connect_fd);

//pthread_create(&tid2,NULL,Write,NULL);

pthread_join(tid,NULL);

//pthread_detach(tid2);

close(sockfd);

return 0;

}

这就是创建TCP和UDP多线程服务器的代码,内容比较简单,具体流程可以参考我的博客,https://blog.csdn.net/Travelerwz/article/details/82084468,不懂得,大家可以私信我,谢谢!!

识别二维码,关注我们

CPP后台服务器开发

linux|shell|C/C++|python

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190120G0URZO00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券