这个例子写得不错,值得参考学习,经过小的修改,我在AIX 5.3上编译 通过,测试也基本达到预期,至于详细的理解,有待完善 ……
-
- struct sockaddr_in {
- short int sin_family; /* 地址族 */
- unsigned short int sin_port;/* 端口号 */
- struct in_addr sin_addr; /* IP地址 */
- unsigned char sin_zero[8]; /*填充0以保持与struct sockaddr同样大小*/
- };
- bzero()或memset()函数将sockaddr_in 声明的结构置为零。
- 为了建立Socket,程序可以调用Socket函数,该函数返回一个类似于文件描述符的句柄。socket 函数原型为: int socket(int domain, int type, int protocol);
- domain指明所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP协议族);type参数指定socket的类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议;protocol通常赋值"0"。Socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。
- int bind(int sockfd,struct sockaddr *my_addr, int addrlen);
- Sockfd是调用socket函数返回的socket描述符,my_addr是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针;addrlen常被设置为sizeof(struct sockaddr)。
- 计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。Internet上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在Internet上传输数据时就需要进行转换,否则就会出现数据不一致。
- 下面是几个字节顺序转换函数:
- htonl():把32位值从主机字节序转换成网络字节序
- htons():把16位值从主机字节序转换成网络字节序
- ntohl():把32位值从网络字节序转换成主机字节序
- ntohs():把16位值从网络字节序转换成主机字节序
- accept()函数让服务器接收客户的连接请求。在建立好输入队列后,服务器就调用accept函数,然后 睡眠并等待客户的连接请求。
- int accept(int sockfd, void *addr, int *addrlen);
- sockfd是被监听的socket描述符,addr通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息(某台主机从某个端口发出该请求);addrten通常为一个指向值为sizeof(struct sockaddr_in)的整型指针变量。出现错误时accept函数返回-1并置相应的errno值。
- Send()函数原型为:
- int send(int sockfd, const void *msg, int len, int flags);
- Sockfd是你想用来传输数据的socket描述符;msg是一个指向要发送数据的指针;Len是以字节为单位的数据的长度;flags一般情况下置为0。
- recv()函数原型为:
- int recv(int sockfd,void *buf,int len,unsigned int flags);
- Sockfd是接受数据的socket描述符;buf 是存放接收数据的缓冲区;len是缓冲的长度。Flags也被置为0。Recv()返回实际上接收的字节数,当出现错误时,返回-1并置相应的errno值。
- 相关文章介绍 : http://fanqiang.chinaunix.net/a4/b7/20010626/150001679.html
- /*
- * Sever code
- */
- #include<stdio.h>
- #include<stdlib.h>
- #include<unistd.h>
- #include<sys/socket.h>
- #include<sys/wait.h>
- #include<arpa/inet.h>
- #include<netinet/in.h>
- #include<string.h>
- #define PORT 9877
- #define BUFLEN 1024
- #define MAXLEN 128
- #define BACKLOG 10
- void getbuf(char *buf,int sockfd);
- void reversebuf(char *buf);
- int main(int argc,char *argv[])
- {
- /*init serversockfd,clientsockfd;*/
- int listenfd,connectfd;
- int clientaddrlen;
- int status;
- struct sockaddr_in clientaddr,serveraddr; /*Gong setting*/
- socklen_t sin_size;
- char buf[BUFLEN];
- pid_t pid;
- char *welcome = "Connect to server successful. Welcome!!!/n";
- if((listenfd=socket(AF_INET,SOCK_STREAM,0)) < 0)
- {
- /*create socket if failure exit*/
- perror("create socket error!");
- exit(1);
- }
- /*init serveraddr*/
- bzero(&serveraddr,sizeof(serveraddr));
- serveraddr.sin_family=AF_INET;
- serveraddr.sin_port=htons(PORT);
- serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
- /*bind port and serveraddr to listenfd*/
- if(bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(struct sockaddr))<0)
- {
- perror("bind port failure!");
- exit(1);
- }
- if(listen(listenfd,BACKLOG) < 0)
- {
- perror("listen error");
- exit(1);
- }
- for(;;)
- {
- /*clientaddrlen=sizeof(clientaddr);*//* Gong setting */
- sin_size = sizeof(struct sockaddr_in);
- if((connectfd=accept(listenfd,(struct sockaddr*)&clientaddr,&sin_size))<0)
- {
- perror("accept from client failure!");
- exit(1);
- }
- printf("Received client: %s request/n",inet_ntoa(clientaddr.sin_addr));
- if((pid=fork()) < 0)
- {
- perror("fork error");
- exit(1);
- }
- else if(pid == 0)
- {
- getbuf(buf,connectfd);
- printf("Get client string : %s/n",buf);
- if(send(connectfd,welcome,strlen(welcome),0) < 0)
- {
- perror("send welcome failure");
- exit(1);
- }
- reversebuf(buf); /*reverse buf*/
- /*send reversed string to client*/
- if(send(connectfd,buf,strlen(buf),0) < 0)
- {
- perror("send reversed string error");
- exit(1);
- }
- close(connectfd);
- exit(0);
- }
- close(connectfd);
- } /** End for loop **/
- close(connectfd);
- close(listenfd);
- exit(0);
- }/** End main function **/
- /*
- * getbuf()
- */
- void getbuf(char *buf,int sockfd)
- {
- char tempbuf[MAXLEN];
- int n;
- int i,index;
- index = 0;
- n = 0;
- /*while( (n=recv(sockfd,tempbuf,MAXLEN,0))>0 )*/
- if((n=recv(sockfd,tempbuf,MAXLEN,0)) > 0)
- {
- for(i=0; i<n; i++)
- buf[index++]=tempbuf[i];
- }
- buf[index]='/0';
- if(n < 0)
- {
- perror("recv error");
- exit(1);
- }
- }
- /*
- * reversebuf()
- */
- void reversebuf(char *buf)
- {
- char c;
- int i,len;
- int mid=(int)len/2;
- len=strlen(buf);
- for(i=0; i<mid; i++)
- {
- c=buf[i];
- buf[i]=buf[len-1-i];
- buf[len-1-i]=c;
- }
- }
- /*
- * Client code
- */
- #include<stdio.h>
- #include<stdlib.h>
- #include<unistd.h>
- #include<sys/socket.h>
- #include<arpa/inet.h>
- #include<netinet/in.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #include<string.h>
- #include<sys/time.h>
- #define PORT 9877
- #define BUFLEN 1024
- #define MAXLEN 128
- #define MAXSLEEP 128
- int connect_retry(int sockfd,struct sockaddr *addr,socklen_t alen);
- void printbuf(int sockfd);
- void getbuf(int sockfd,char *buf);
- int main(int argc,char *argv[])
- {
- int sockfd;
- struct sockaddr_in serveraddr;
- int addrlen;
- pid_t pid;
- char *str = "Gong Yao";
- /*char buf[BUFLEN];*/
- if(argc != 2)
- {
- printf(" Pls follow : clienttest ipaddress/n");
- exit(1);
- }
- if((sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0)
- {
- perror("create socket error");
- exit(1);
- }
- bzero(&serveraddr,sizeof(serveraddr));
- serveraddr.sin_family=AF_INET;
- serveraddr.sin_port=htons(PORT);
- inet_pton(AF_INET,argv[1],&serveraddr.sin_addr);
- addrlen=sizeof(struct sockaddr);
- if(connect_retry(sockfd,(struct sockaddr *)&serveraddr,addrlen) < 0)
- {
- printf("connect to server error /n");
- exit(1);
- }
- if(send(sockfd,str,strlen(str),0) < 0)
- {
- perror("send str to server error");
- exit(1);
- }
- /*fflush(sockfd);*//*Gong setting*/
- printbuf(sockfd);
- close(sockfd);
- exit(0);
- }/** End main function **/
- /*
- * connect_retry()
- */
- int connect_retry(int sockfd,struct sockaddr *addr,socklen_t alen)
- {
- int nsec;
- for(nsec=1; nsec<MAXSLEEP; nsec<<=1)
- {
- if(connect(sockfd,addr,alen) == 0)
- return 0 ;
- if(nsec<=MAXSLEEP/2)
- sleep(nsec);
- }
- return (-1);
- }
- /*
- * printbuf()
- */
- void printbuf(int sockfd)
- {
- char buf[BUFLEN];
- fd_set rfd;
- struct timeval timeout;
- timeout.tv_sec = 10;
- timeout.tv_usec = 0;
- FD_ZERO(&rfd);
- FD_SET(sockfd,&rfd);
- switch(select(sockfd+1,&rfd,NULL,NULL,&timeout))
- {
- case -1:
- perror("select error");
- exit(1);
- case 0:
- printf("receive data from server timeout");
- break;
- default:
- getbuf(sockfd,buf);
- printf("Get string from server : ");
- printf("%s",buf);
- break;
- }
- printf("/n");
- }
- /*
- * getbuf()
- */
- void getbuf(int sockfd,char *buf)
- {
- char tempbuf[MAXLEN];
- int i,n,index;
- n = 0;
- index = 0;
- while((n=recv(sockfd,tempbuf,MAXLEN,0)) > 0)
- {
- for(i=0; i<n; i++)
- buf[index++]=tempbuf[i];
- }
- buf[index]='/0';
- if(n < 0)
- {
- perror("recv data from server error");
- exit(1);
- }
- }
-