这里主要是代码,网上有原理
socket 有同步,异步之分,我这是个同步的,同步又有阻塞和非阻塞之分,
这的非阻塞是用select()函数实现的
客户端:
#include <errno.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define servport 2000
#define maxdatasize 100
int main(int argc,char ** argv){
int sockfd,recvbytes,f;
char buf[maxdatasize];
struct hostent *host;
struct sockaddr_in serv_addr;
fd_set rfds,wfds;
struct timeval timeout={10,0};
if(argc<2){
printf("please enter the service's hostname!\n");
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL){
perror("gethostbyname error");
exit(0);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("create socker error");
exit(0);
}
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(servport);
serv_addr.sin_addr=*((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1){
perror("connect error");
exit(1);
}
while(1){
tt:
// tt
usleep(1000);
FD_ZERO(&rfds);
FD_SET(sockfd,&rfds);
FD_ZERO(&wfds);
FD_SET(sockfd,&wfds);
f=select(sockfd+1,&rfds,&wfds,NULL,&timeout);
switch(f){
case -1:
perror("error");
exit(0);
case 0:
perror("等待超时");
goto tt ;
default:
if(FD_ISSET(sockfd,&rfds)){
read(sockfd,&buf,50);
printf("server data is :%s",&buf);
}
if(FD_ISSET(sockfd,&wfds)){
write(sockfd,"$GPRMC,011728.000,A,3029.1966,N,11424.2966,E,8.34,280.72,110409,,,A*67",sizeof("$GPRMC,011728.000,A,3029.1966,N,11424.2966,E,8.34,280.72,110409,,,A*67"));
printf("sent success");
}
}
/**
if(f<=0){
perror("select error");
printf("connect error,sleep 1000");
usleep(1000);
continue ;
}
if(FD_ISSET(sockfd,&rfds)){
read(sockfd,&buf,50);
printf("read data is:%s",&buf);
}
if(FD_ISSET(sockfd,&wfds)){
write(sockfd,"icome from client",50);
printf("client write something to server");
}
**/
/**
if((recvbytes=read(sockfd,&buf,50))==-1){
perror("read error");
exit(0);
}
buf[recvbytes]='\0';
printf("read server val:%s",buf);
printf("enter content:");
**/
// int num=0;
// while((content[num++]=getchar())!='\n');
/**
if(send(sockfd,&gd,sizeof(struct gpsdata),0)==-1){
perror("write error");
exit(0);
}
**/
// write(sockfd,"\n",2);
}
return 0;
}//main
服务器端:
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <errno.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define SERVPORT 3333
#define BACKLOG 10
#define dataSize 100
main(){
int sockfd,client_fd;
struct sockaddr_in my_addr;
struct sockaddr_in remote_addr;
char buf[dataSize] ;
fd_set rfds,wfds;
struct timeval timeout={3,0};
int tags;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
perror("socket create erro");
exit(1);
}
my_addr.sin_port=htons(SERVPORT);
my_addr.sin_family=AF_INET;
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&(my_addr.sin_zero),8);
if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1){
perror("bind error");
exit(1);
}
if(listen(sockfd,BACKLOG)==-1){
perror("lister error");
exit(1);
}
while(1) {
int sin_size=sizeof(struct sockaddr_in);
if((client_fd=accept(sockfd,(struct sockaddr *)&remote_addr,&sin_size))==-1){
perror("accept error");
continue;
}
printf("received a connection from %s\n",inet_ntoa(remote_addr.sin_addr));
if(!fork()){
char content[50];
while(1){
gg:
FD_ZERO(&rfds);
FD_SET(client_fd,&rfds);
FD_ZERO(&wfds);
FD_SET(client_fd,&wfds);
tags=select(client_fd+1,&rfds,&wfds,NULL,&timeout);
switch(tags){
case -1:
printf("出错");
exit(-1); break;
case 0:
printf("没有数据");
continue gg ;
default:
if(FD_ISSET(client_fd,&rfds)){
read(client_fd,&content,50);
printf("client data is :%s",&content);
}
if(FD_ISSET(client_fd,&wfds)){
write(client_fd,"i come from server ",50);
}
break;
}
}
close(client_fd);
exit(0);
}
}
}
分享到:
评论