有人懂linux下的socket编程的吗?

smood 2003-07-30 01:40:11
用流socket做一个服务器端用于数据转发,多IP的,
...全文
36 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
axlw 2003-08-10
  • 打赏
  • 举报
回复
西安电子科技出版社《实战linux socket编程》
daehappy 2003-08-04
  • 打赏
  • 举报
回复

if (r<1)
{
if (r == 0)
cout<<"fwd_to["<<i<<"] has closed the connection ! and read action returns zero !"<<endl;

shut_fd(&cq,i);
}
else
cq.fi[i].buf_fd_avail +=r;

nsel --;
}

if (FD_ISSET(fd,&wds))
{
r= write(fd,cq.fi[i].buf_sd+cq.fi[i].buf_sd_written,cq.fi[i].buf_sd_avail-cq.fi[i].buf_sd_written);

if (r<1)
{
if (r == 0)
cout<<"fwd_to["<<i<<"] has closed the connection ! and write action returns zero !"<<endl;

shut_fd(&cq,i);
}
else
cq.fi[i].buf_sd_written += r;

nsel --;
}

shutflag = 1;
} // end of : if (fd>0)

//check if write data has caught read data
if (cq.fi[i].buf_sd_written == cq.fi[i].buf_sd_avail)
cq.fi[i].buf_sd_written = cq.fi[i].buf_sd_avail = 0;

if (cq.fi[i].buf_fd_written == cq.fi[i].buf_fd_avail)
cq.fi[i].buf_fd_written = cq.fi[i].buf_fd_avail = 0;

//one side has closed the connection,
//keep writing to the other side until empty
if (cq.fi[i].sd<0 && cq.fi[i].buf_sd_avail==cq.fi[i].buf_sd_written)
shut_fd(&cq,i);

if (cq.fi[i].fd<0 && cq.fi[i].buf_fd_avail==cq.fi[i].buf_fd_written)
shut_sd(&cq,i);

//resource recycling
if (shutflag == 1)
if (cq.fi[i].sd<0 && cq.fi[i].fd<0)
{
cout<<"connection["<<i<<"] recycled !"<<endl;

cq.navail ++;
}
} // end of : for (i=0;i<FWD_MAX && nsel>0;i++)
} // end of : for(;;)

return 0;
} // end of : main()

static int listen_socket(int listen_port)
{
struct sockaddr_in addr;
int s;
int yes;

if ((s=socket(AF_INET,SOCK_STREAM,0))<0)
{
cout<<"socket() for fwd_from func. error :"<<strerror(errno)<<endl;
return -1;
}

yes=1;

if (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes))<0)
{
cout<<"setsockopt() func. error : "<<strerror(errno)<<endl;
close(s);
return -1;
}

//i = fcntl(s,F_GETFL,0);
//fcntl(s,F_SETFL,i | O_NONBLOCK);

bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(listen_port);
addr.sin_addr.s_addr = htonl(INADDR_ANY); //书有man没有;

if (bind(s,(struct sockaddr *)&addr,sizeof(addr))<0)
{
cout<<"bind() func. error :"<<strerror(errno)<<endl;
close(s);
return -1;
}

cout<<"accepting connections on port "<<listen_port<<endl;

listen(s,BACKLOG);

return s;
}

void shut_sd(fwd_queue *cq,int i)
{
if (cq->fi[i].sd>=0)
{
shutdown(cq->fi[i].sd,SHUT_RDWR);
close(cq->fi[i].sd);

cq->fi[i].sd = -1;
}
}

void shut_fd(fwd_queue *cq,int i)
{
if (cq->fi[i].fd>=0)
{
shutdown(cq->fi[i].fd,SHUT_RDWR);
close(cq->fi[i].fd);

cq->fi[i].fd = -1;
}
}

void accept_conn(struct fwd_queue *cq)
{
struct sockaddr_in cli,fwd_to;
int cfd,s;
int i,l;

l = sizeof(struct sockaddr_in);
bzero(&cli,l);
cfd = accept(cq->lfd,(struct sockaddr *)&cli,(socklen_t *)&l);

if (cfd<0)
{
cout<<"accept() func. error :"<<strerror(errno)<<endl;

close(cfd);
return;
}
//cout<<"accept() func. ok !"<<endl<<cq->navail<<endl;

if (cq->navail == 0)
{
cout<<"system has reached to the MAX connetions !"<<endl;
cout<<"to change this MAX value, please redefine FWD_MAX !"<<endl;
cout<<"request from "<<inet_ntoa(cli.sin_addr)<<" was refused !"<<endl;

close(cfd);

return;
}

cout<<"accepted fwd request from :"<<inet_ntoa(cli.sin_addr)<<endl;

//不能设置非阻塞,否则转发就变味儿了.
//i = fcntl(cfd,F_GETFL,0);
//fcntl(cfd,F_SETFL,i | O_NONBLOCK);

for (i=0;i<FWD_MAX;i++)
{
if (cq->fi[i].sd<0)
break;
}

cq->fi[i].sd = cfd;
cq->navail --;

cout<<"cq.fi["<<i<<"] is selected"<<endl;

//初始化
strcpy(cq->fi[i].buf_sd,"\0");
strcpy(cq->fi[i].buf_fd,"\0");
cq->fi[i].buf_sd_avail = cq->fi[i].buf_sd_written = 0;
cq->fi[i].buf_fd_avail = cq->fi[i].buf_fd_written = 0;

if ((s= socket(AF_INET,SOCK_STREAM,0))<0)
{
cout<<"socket() func. for fwd_to error :"<<strerror(errno)<<endl;
cout<<"this fwd request failed !"<<endl;

close(s);
shut_sd(cq,i);
}

l = sizeof(struct sockaddr_in);
bzero(&fwd_to,l);

fwd_to.sin_port = htons(fwd_to_port);
fwd_to.sin_family = AF_INET;

if (!inet_aton(fwd_to_ip,(struct in_addr *)&fwd_to.sin_addr.s_addr))
{
cout<<"bad ip address format !"<<endl;
cout<<"this fwd request failed !"<<endl;

close(s);
shut_sd(cq,i);

return;
}

if (connect(s,(struct sockaddr *)&fwd_to,l)<0)
{
cout<<"connect() error :"<<strerror(errno)<<endl;
shutdown(s,SHUT_RDWR);
close(s);

return ;
}

cout<<" this tcp forwording request is ok !"<<endl;
cout<<" WHY NOT START NOW !"<<endl<<endl;

cq->fi[i].fd = s;
}
daehappy 2003-08-04
  • 打赏
  • 举报
回复
exactly for you !!

///////////////
//
// tfm = TCP forwording multiplex
//
// to run : ./a.out 8086 211.148.211.38
//
// to test : telnet 127.0.0.1 8086
//
// then you will se some kind of "George Hill's FTP"
//
// Good luck !
//
///////////////

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>


#define BACKLOG 10
#define FWD_MAX 1024
#define BUF_SIZE 1024

#undef max
#define max(x,y) ((x)>(y)?(x):(y))

struct fwd_queue
{
int navail;
int lfd;

struct fwd_info
{
int sd;
int fd;
char buf_sd[BUF_SIZE];
char buf_fd[BUF_SIZE];
int buf_sd_avail,buf_sd_written;
int buf_fd_avail,buf_fd_written;
}fi[FWD_MAX];
};

static int fwd_to_port;
static char *fwd_to_ip;

static int listen_socket(int listen_port);

void shut_sd(fwd_queue *cq,int i);
void shut_fd(fwd_queue *cq,int i);

void accept_conn(struct fwd_queue *cq);

int main(int argc,char **argv)
{
struct fwd_queue cq;
fd_set rds,wds,eds;
int maxfd=0;
int i,nsel;

//check console input
if (argc != 4)
{
cout<<"Usage: ./a.out listen_port fwd_ip fwd_port"<<endl;
return -1;
}

signal(SIGPIPE,SIG_IGN); //起何作用?

fwd_to_port = atoi(argv[3]);
fwd_to_ip = argv[2];

cq.lfd = listen_socket(atoi(argv[1]));

if (cq.lfd<0)
return -1;

cq.navail = FWD_MAX;

for (i=0;i<FWD_MAX;i++)
{
cq.fi[i].sd = -1;
cq.fi[i].fd = -1;
//别的初始化放在 accept_conn()里面
}

for(;;)
{
int r;

FD_ZERO(&rds);
FD_ZERO(&wds);
FD_ZERO(&eds);

//maxfd = max(maxfd,h); // maxfd = h; 多余?

//if (cq.navail>0)
{
FD_SET(cq.lfd,&rds);
maxfd = max(maxfd,cq.lfd);
}

for (i=0;i<FWD_MAX;i++)
{
if (cq.fi[i].sd>0)
{
if (cq.fi[i].buf_sd_avail<BUF_SIZE)
FD_SET(cq.fi[i].sd,&rds);

if (cq.fi[i].buf_fd_avail>cq.fi[i].buf_fd_written)
FD_SET(cq.fi[i].sd,&wds);

FD_SET(cq.fi[i].sd,&eds);

maxfd = max(maxfd,cq.fi[i].sd);
}

if (cq.fi[i].fd>0)
{
if (cq.fi[i].buf_fd_avail<BUF_SIZE)
FD_SET(cq.fi[i].fd,&rds);

if (cq.fi[i].buf_sd_avail>cq.fi[i].buf_sd_written)
FD_SET(cq.fi[i].fd,&wds);

FD_SET(cq.fi[i].fd,&eds);

maxfd = max(maxfd,cq.fi[i].fd);
}
}// end of : for (i=0;i<FWD_MAX;i++)

nsel = select(maxfd+1,&rds,&wds,&eds,NULL);

if (r==-1 && errno == EINTR)
continue;

if (r<-1)
{
cout<<"select() func. error !"<<errno<<strerror(errno)<<endl;
return (-1);
}

if (FD_ISSET(cq.lfd,&rds))
{
accept_conn(&cq);

nsel--;
}

// NB: read oob data before normal reads
for (i=0;i<FWD_MAX && nsel>0;i++)
{
//假如编程开始就使用以下类似语句,书写效率会高不少;
//也不容易出错;
const int sd = cq.fi[i].sd,fd = cq.fi[i].fd;
int shutflag = 0;


//把man例子顺序稍微调整了一下。
if (sd>0)
{
if (FD_ISSET(sd,&eds))
{
char c;

errno = 0;
r = recv(sd,&c,1,MSG_OOB);

if (r<1)
{
if (r == 0)
cout<<"some error on fwd_from["<<i<<"] !"<<endl;

shut_sd(&cq,i);
}
else
send(fd,&c,1,MSG_OOB);

nsel --;
}

if (FD_ISSET(sd,&rds))
{
r= read(sd,cq.fi[i].buf_sd+cq.fi[i].buf_sd_avail,BUF_SIZE-cq.fi[i].buf_sd_avail);

if (r<1)
{
if (r == 0)
cout<<"fwd_from["<<i<<"] has closed the connection ! and read action returns !"<<endl;

shut_sd(&cq,i);
}
else
cq.fi[i].buf_sd_avail += r;

nsel --;
}

if (FD_ISSET(sd,&wds))
{
r= write(sd,cq.fi[i].buf_fd+cq.fi[i].buf_fd_written,cq.fi[i].buf_fd_avail-cq.fi[i].buf_fd_written);
if (r<1)
{
if (r == 0)
cout<<"fwd_from["<<i<<"] has closed the connection ! and write action returns zero !"<<endl;

shut_sd(&cq,i);
}
else
cq.fi[i].buf_fd_written +=r;

nsel --;
}

shutflag = 1;
} // end of : if (sd>0)

if (fd>0)
{
if (FD_ISSET(fd,&eds))
{
char c;
errno = 0;

r = recv(fd,&c,1,MSG_OOB);

if (r<1)
{
if (r == 0)
cout<<"some error fwd_to["<<i<<"] !"<<endl;

shut_sd(&cq,i);
}
else
send(sd,&c,1,MSG_OOB);

nsel --;
}

if (FD_ISSET(fd,&rds))
{
r= read(fd,cq.fi[i].buf_fd+cq.fi[i].buf_fd_avail,BUF_SIZE-cq.fi[i].buf_fd_avail);
numchun 2003-08-01
  • 打赏
  • 举报
回复
你随便找几本关于网络编程的书籍就可以搞定了,很简单的。
joyfire 2003-07-31
  • 打赏
  • 举报
回复
给你个资料,希望有用
http://joyfire.net/jln/system/9.html
kevinhewanjun 2003-07-30
  • 打赏
  • 举报
回复
直接用C写,程序效率较高
cool_killer 2003-07-30
  • 打赏
  • 举报
回复
我懂。
要做什么?
AceHuang 2003-07-30
  • 打赏
  • 举报
回复
用java就可以实现

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧