socket例子及高級用法

使用SIGALRM信號爲阻塞操作設置超時

可以處理connect和read等超市

https://blog.csdn.net/lstok2009/article/details/50100529

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


#define MAXLINE 4096

typedef void (*sighandler_t)(int);
#define		TIMEOUT_SET

static void connect_alarm(int sig_num)
{
	//sig num is 14
	printf("connect_alarm signal num:%d\n", sig_num);	
	return;
}
static void now_alarm(int sig_num)
{
	printf("now_alarm signal num:%d\n", sig_num);	
	return;
} 
int main(int argc, char** argv)
{
	int    sockfd, n;
	char    recvline[4096], sendline[4096];
	struct sockaddr_in    servaddr;
	char server_ip[50] = {0};
	sighandler_t p;
	unsigned int remain_sec;
	struct sigaction sa_alarm;
 
	if( argc != 2){
		printf("usage: ./client <ipaddress>\n");
		printf("use local addr:'0.0.0.0'\n");
		strcpy(server_ip, "0.0.0.0");
	} else {
		strcpy(server_ip, argv[1]);
	}
 
	if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
	// 創建套接字描述符給sockfd
		printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
		exit(0);
	}
 
	memset(&servaddr, 0, sizeof(servaddr));
	//結構體清零
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(6666);//端口號
	if( inet_pton(AF_INET, server_ip, &servaddr.sin_addr) <= 0){
	//Linux下IP地址轉換函數,可以在將IP地址在“點分十進制”和“整數”之間轉換 
		printf("inet_pton error for %s\n",argv[1]);
		exit(0);
	}
  printf("connect to server here~~~maybe wait here\n");
  #ifdef TIMEOUT_SET
  #if 0
  p = signal(SIGALRM, connect_alarm);
  if(p == SIG_ERR) {
  	perror("signal error");	
  	exit(0);
  }
  printf("p:%p connect_alarm:%p\n", p, connect_alarm);
  #else
  sa_alarm.sa_flags = SA_RESETHAND;
  sa_alarm.sa_handler = connect_alarm;
  sigaction(SIGALRM, &sa_alarm, NULL);
    
  #endif
  
  
  remain_sec = alarm(5);
  printf("remain sec:%d\n", remain_sec);
	if(remain_sec != 0) {
		perror("previous alarm set before");
		exit(0);
	}
	//while(1);
  #if 0
  //set to null
  p = signal(SIGALRM, p);
  if(p == SIG_ERR) {
  	perror("signal error");	
  	exit(0);
  }
  printf("p:%p connect_alarm:%p\n", p, connect_alarm);  
  #endif
  
  
  #endif
	if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
	//連接請求
		printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
		exit(-1);
	}
 
	printf("send msg to server: \n");
	fgets(sendline, 4096, stdin);
	if( send(sockfd, sendline, strlen(sendline), 0) < 0)
	{
		printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
		exit(0);
	}
 
	close(sockfd);
	exit(0);
}

 

常規例子

server.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
 
#define MAXLINE 4096
 
int main(int argc, char** argv)
{
	int    listenfd, connfd;
	struct sockaddr_in     servaddr;
	char    buff[4096];
	int     n;
 
	if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
		printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
		exit(0);
	}
 
	memset(&servaddr, 0, sizeof(servaddr));
	//協議地址
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(6666);//
	//bind把一個地址族中的特定地址賦給socket
	if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
		printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
		exit(0);
	}
 
	if( listen(listenfd, 10) == -1){
	//listen 監聽
		printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
		exit(0);
	}
 
	printf("======waiting for client's request======\n");
	while(1){
		if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){
			printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
			continue;
		}
		n = recv(connfd, buff, MAXLINE, 0);
		buff[n] = '\0';
		printf("recv msg from client: %s\n", buff);
		close(connfd);
	 }
 
		close(listenfd);
}

client.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
 
#define MAXLINE 4096
 
int main(int argc, char** argv)
{
	int    sockfd, n;
	char    recvline[4096], sendline[4096];
	struct sockaddr_in    servaddr;
 
	if( argc != 2){
		printf("usage: ./client <ipaddress>\n");
		exit(0);
	}
 
	if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
	// 創建套接字描述符給sockfd
		printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
		exit(0);
	}
 
	memset(&servaddr, 0, sizeof(servaddr));
	//結構體清零
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(6666);//端口號
	if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
	//Linux下IP地址轉換函數,可以在將IP地址在“點分十進制”和“整數”之間轉換 
		printf("inet_pton error for %s\n",argv[1]);
		exit(0);
	}
 
	if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
	//連接請求
		printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
	}
 
	printf("send msg to server: \n");
	fgets(sendline, 4096, stdin);
	if( send(sockfd, sendline, strlen(sendline), 0) < 0)
	{
		printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
		exit(0);
	}
 
	close(sockfd);
	exit(0);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章