socket通信示例程序

简单socket通信的服务器端程序如下:


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

#define  SERVER_PORT  3456
#define  DEBUG        0			//debug macro
#define  TRUE   	  1
#define  FALSE 		  0



int
main(int argc,char **argv){
	int listen_sfd,max_sfd,new_sfd;
	int on=1,rv,ready_sfd_num,i,connection_close=FALSE,server_end=FALSE;
	fd_set master_set,working_set;
	struct sockaddr_in sockaddr;
	struct timeval timeout;
	char buf[100];

	/*
	 * create a AF_INET SOCKET_STREAM socket
	 * */
	listen_sfd=socket(AF_INET,SOCK_STREAM,0);
	if(listen_sfd < 0){
		perror("server socket ");
		exit(EXIT_FAILURE);
	}

#if DEBUG
	printf("listen_sfd=%d\n",listen_sfd);
#endif

	/*
	 * set socket to SO_REUSEADDR
	 * */
	rv=setsockopt(listen_sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&on,sizeof(on));
	if(rv < 0){
		perror("server setsockopt");
		close(listen_sfd);
		exit(EXIT_FAILURE);
	}

	/*
	 * set socket to non-blocking
	 * */
	rv=fcntl(listen_sfd,F_SETFL,O_NONBLOCK);
	if(rv<0){
		perror("server fcntl ");
		close(listen_sfd);
		exit(EXIT_FAILURE);
	}

	/*
	 * bind socket to localhost interface
	 * */
	memset(&sockaddr,0,sizeof(sockaddr));
	sockaddr.sin_family     =AF_INET;
	sockaddr.sin_port		=htons(SERVER_PORT);
	sockaddr.sin_addr.s_addr=htonl(INADDR_ANY);
	rv=bind(listen_sfd,(struct sockaddr *)&sockaddr,sizeof(sockaddr));
	if(rv<0){
		perror("server bind ");
		close(listen_sfd);
		exit(EXIT_FAILURE);
	}

	/*
	 * set back log to 10
	 * */
	rv=listen(listen_sfd,10);
	if(rv<0){
		perror("server listen ");
		close(listen_sfd);
		exit(EXIT_FAILURE);
	}

	/*
	 * file descriptors set operations
	 * */
	FD_ZERO(&master_set);
	FD_ZERO(&working_set);
	max_sfd=listen_sfd;
	FD_SET(listen_sfd,&master_set);

	/*
	 * infinite loop of select
	 * */
	while(1){
		memcpy(&working_set,&master_set,sizeof(master_set));

		/*
		 * set timeout value to 2 minutes
		 * */
		timeout.tv_sec =2*60;
		timeout.tv_usec=0;

		ready_sfd_num=select(max_sfd+1,&working_set,NULL,NULL,&timeout);
		/*
		 * select return value has three conditions:
		 * 1.<0 ---error
		 * 2.==0---timeout value expires
		 * 3.>0 ---successful
		 * */
		if(ready_sfd_num<0){
			perror("server select ");
			break;
		}

		if(ready_sfd_num==0){
			printf("Time Out,End Program!\n");
			break;
		}

		/*
		 * when select function is invoked successfully,there exists two conditions:
		 * 1.new connections
		 * 2.new data
		 * */
		for(i=0;i<=max_sfd && ready_sfd_num>0;++i){

			if(FD_ISSET(i,&working_set)){
				ready_sfd_num--;
				/*
				 * new connection coming ,accept all incoming connections in queue list
				 * */
				if(i==listen_sfd){
					while(1){
						new_sfd=accept(listen_sfd,NULL,NULL);

						if(new_sfd <0){
							if(errno != EWOULDBLOCK){
								perror("server accept");
								server_end=TRUE;
							}
							break;
						}

						if(new_sfd >0){
							/*
							 * set new_sfd to non-blocking
							 * */
							rv=fcntl(new_sfd,F_SETFL,O_NONBLOCK);
							if(rv<0){
								perror("server fcntl ");
								close(new_sfd);
								break;
							}

							FD_SET(new_sfd,&master_set);
							if(new_sfd>max_sfd)
								max_sfd=new_sfd;
							printf("new connection created,socket---%d\n",new_sfd);


						}
					}
				}

				/*
				 * new data coming on connected socket
				 * */
				else{
					while(1){
						rv=recv(i,buf,sizeof(buf),0);
						if(rv<0){
							if(errno != EWOULDBLOCK ){
								perror("servre recv");
								connection_close=TRUE;
							}
							break;
						}

						if(rv==0){
							connection_close=TRUE;
							break;
						}

						printf("server receive:%s,from socket---%d\n",buf,i);
					}
				}
				if(connection_close){
					close(i);
					printf("%d socket closed!\n",i);
					FD_CLR(i,&master_set);
					if(i==max_sfd){
						while(FD_ISSET(max_sfd,&master_set)==FALSE)
							max_sfd--;
					}
				}
			}
		}//end of ready sfd loop

	/*determine whether end server or not*/
		if(server_end)
			break;
	}//end of select

	/*
	 * cleanup
	 * */
	while(max_sfd>=0){
		if(FD_ISSET(max_sfd,&master_set))//which one :working_set or master_set!!!!master_set
			close(max_sfd);
		max_sfd--;
	}

	return 0;
}//end of main


客户端程序如下:

/*
** client.c -- a stream socket client demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include <arpa/inet.h>

#define PORT "9034" // the port client will be connecting to

#define MAXDATASIZE 100 // max number of bytes we can get at once

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
	if (sa->sa_family == AF_INET) {
		return &(((struct sockaddr_in*)sa)->sin_addr);
	}

	return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(int argc, char *argv[])
{
	int sockfd, numbytes;
	char buf[MAXDATASIZE];
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];

	if (argc != 2) {
	    fprintf(stderr,"usage: client hostname\n");
	    exit(1);
	}

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if ((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
		return 1;
	}

	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype,
				p->ai_protocol)) == -1) {
			perror("client: socket");
			continue;
		}

		if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(sockfd);
			perror("client: connect");
			continue;
		}

		break;
	}

	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\n");
		return 2;
	}

	inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
			s, sizeof s);
	printf("client: connecting to %s\n", s);

	freeaddrinfo(servinfo); // all done with this structure

	if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
	    perror("recv");
	    exit(1);
	}

	buf[numbytes] = '\0';

	printf("client: received '%s'\n",buf);

	close(sockfd);

	return 0;
}




  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coffee_baba

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值