您的位置:首页 > 理论基础 > 计算机网络

UNP——TCP回射服务器

2020-07-01 17:57 106 查看

非阻塞connect
server

#include <stdio.h>
#include <stdlib.h>
#include "tcpser.h"
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/select.h>
#include <errno.h>

#define LISTSIZE 50
//#define MAX(a,b)((a)>(b)? (a):(b))
#define ADDRBUFFER 50
#define RECV_BUFSIZE 1024
int main()
{
fd_set* r_set,w_set,e_set;
int sd,wd;
int nsd;
ssize_t num;
int flag;
char recv_buffer[RECV_BUFSIZE];
char addr_buffer[ADDRBUFFER];
struct sockaddr_in laddr, raddr;
struct timeval timel;
timel.tv_sec = 60;
int raddr_size = sizeof(raddr);
// fp = fopen();
// int fd = fileno(fp);
sd = socket(AF_INET,SOCK_STREAM,0);
if(sd<0)
{
perror("socket");
exit(1);
}
if(setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag))<0)
{
perror("setsockopt");
exit(1);
}
laddr.sin_family = AF_INET;
laddr.sin_port = htons(PORT);
inet_pton(AF_INET,"0.0.0.0",(void*)&laddr.sin_addr);
if(bind(sd,(void*)&laddr,sizeof(laddr))<0)
{
perror("bind");
exit(1);
}
if(listen(sd,LISTSIZE)<0)
{
perror("listen");
exit(1);
}

while(1)
{

FD_ZERO(r_set);
//FD_ZERO(w_set);
FD_SET(sd,r_set);
//FD_SET(fd,w_set);

switch(select(sd+1,r_set,NULL,NULL,&timel))
{
case 0:
{
fprintf(stdout,"timeout\n");
break;
}
case -1:
{
if(errno == EINTR)
continue;
else
{
perror("select");
break;
}
}
default:
{
if(FD_ISSET(sd,r_set))
{
nsd = accept(sd,(void*)&raddr,(void*)&raddr_size);
if( nsd < 0)
{
perror("accept");
exit(1);
}
inet_ntop(AF_INET,(void*)&raddr.sin_addr,addr_buffer,ADDRBUFFER);
printf("the client ip is %s, port is %d\n",addr_buffer,ntohs(raddr.sin_port));
while(1)
{
num = recv(nsd,recv_buffer,RECV_BUFSIZE,0);
if(num == 0)
{
printf("end \n");
break;
}
else if(num<0)
{
perror("recv");
exit(1);
}
if(write(nsd,recv_buffer,num)<0)
{
perror("write");
exit(1);
}
}
close(nsd);
}
}
}

}

close(sd);
exit(0);

}

client,connect非阻塞版本

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <string.h>
#include <strings.h>
#include "tcpser.h"
#include <fcntl.h>
#include <errno.h>

#define MAXLINE 1024

int main(int argc, char* argv[])
{
int sockfd;
int n;
struct sockaddr_in servaddr;
char buf[MAXLINE];
fd_set rset, wcoset;
int maxfd;
int stdineof;

if(argc != 2){
printf("invalid usage!\n");
exit(1);
}

if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("socket");
exit(1);
}

servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
inet_pton(AF_INET,  argv[1], &servaddr.sin_addr);

int fcmd = fcntl(sockfd,F_GETFL,0); //返回原来的文件标志
fcntl(sockfd,F_SETFL,O_NONBLOCK|fcmd); //在原来的文件标志的基础上增加非阻塞标志

if(connect(sockfd, (void*)&servaddr, sizeof(servaddr)) < 0){
//perror("socket");
if(errno == EINPROGRESS)
{
FD_SET(0, &wcoset);
FD_SET(sockfd, &wcoset);
if(select(sockfd+1,NULL,&wcoset,NULL,NULL)<0)
{
perror("select");
exit(1);
}
if(FD_ISSET(sockfd, &wcoset))
{
int flag;
socklen_t sflag = sizeof(flag);
if(getsockopt(sockfd,SOL_SOCKET,SO_ERROR,(void*)&flag,&sflag)<0)
{

printf("the error is : %s\n",strerror(flag));
exit(1);
}
printf("conncet 2 successifully\n");
}
}

}
else
{
printf("conncet 1 successifully\n");
}

maxfd = sockfd;
FD_ZERO(&rset);
stdineof = 0;

while(1){
if(stdineof == 0)
FD_ZERO(&rset);
FD_SET(sockfd, &rset);

if((n = select(maxfd+1, &rset, NULL, NULL, NULL)) < 0){
printf("select error\n");
exit(1);
}

if(FD_ISSET(0, &rset)){
if((n = read(0, buf, MAXLINE)) == 1){
printf("shutdown ready\n");
stdineof = 1;
if(shutdown(sockfd, SHUT_RD) < 0){
perror("shutdown");
exit(1);
}
FD_CLR(0, &rset);
continue;
}
else if(n < 0){
perror("read");
exit(1);
}
if((n = write(sockfd, buf, n)) < 0){
perror("write");
exit(1);
}
}

if(FD_ISSET(sockfd, &rset)){
if((n = read(sockfd, buf, MAXLINE)) == 0){
if(stdineof == 1)
break;
else{
printf("server terminated\n");
exit(1);
}
}
else if(n < 0){
perror("read");
exit(1);
}
if((n = write(1, buf, n)) < 0){
perror("write");
exit(1);
}
}
}
return 0;
}

h文件

#ifndef TCPSER_H_
#define TCPSER_H_

#define PORT 2010

#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: