linux socket编程 出现信号SIGPIPE

服务端程序: 

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

#define PORT (1234)
#define SIZE (16)
#define STR_HELLO "Hello"
#define STR_OK "OK"

int create_socket();
int wait_client( int listen_socket );
void *handle_message(void *client_socket_h);
int unpack_str( char *msg );
int pack_str( char *str , int index );

int main()
{
	int listen_socket = create_socket();
	int client_socket;
	while(1)
	{
		client_socket = wait_client(listen_socket);
		if( client_socket == -1 )
		{	
			return 0;
		}
		else
		{

			pthread_t handle_pid;
			int ret = pthread_create( &handle_pid, NULL, handle_message, (void *)(&client_socket) );
			pthread_detach(handle_pid);
		}
	}
	close(client_socket);		
	close(listen_socket);
	
	return 0;
}

int create_socket()
{
	int listen_socket = socket( AF_INET, SOCK_STREAM, 0 );
	if( listen_socket == -1 )
	{
		perror("socket");
		return -1;
	}
	struct sockaddr_in addr;
	memset( &addr, 0, sizeof(addr) );
	addr.sin_family = AF_INET;
	addr.sin_port   = htons(PORT);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	int ret = bind( listen_socket, (struct sockaddr *)&addr, sizeof(addr) );
	if( ret == -1 )
	{
		perror("bind");
		return -1;
	}
	
	ret = listen( listen_socket, 2 );
	if( ret == -1 )
	{
		perror("listen");
		return -1;
	}
	return listen_socket;
}

int wait_client( int listen_socket )
{
	struct sockaddr_in client_addr;
	int addrlen = sizeof(client_addr);
	printf("service:wait for client connect\n");
	int client_socket = accept( listen_socket, (struct sockaddr *)(&client_addr), &addrlen );
	if( client_socket == -1 )
	{
		perror("accept");
		return -1;
	}

	printf("service:%s send data\n" , inet_ntoa(client_addr.sin_addr));
	return client_socket;
}


void *handle_message(void *client_socket_h)
{
	char msg[SIZE];
	int client_socket = *((int *)client_socket_h);
	while(1)
	{
		int ret = read( client_socket , msg , SIZE );
		if(ret == -1)
		{
			perror("read");
			close(client_socket);
			exit(1);
		}
		if(ret > 0)	
		{
			int index = unpack_str(msg);
			char res[SIZE];
			pack_str( res , index );
			ret = write( client_socket , res , SIZE );
		}	
		usleep(100);		
	}

}

int unpack_str(char *msg)
{
	printf("service:msg = %s\n" , msg);
	char *str_hello = (char *)malloc(SIZE);
	char *str_num = (char *)malloc(SIZE);
	if( strstr( msg, STR_HELLO ) == NULL )
	{
		printf("service:have not hello\n");
		printf("service:msg = %s\n" , msg);
		free(str_hello);
		free(str_num);
		return -1;
	}
	else
	{
		str_num = msg + strlen(STR_HELLO);
		//printf("service :have hello\n");
		//printf("service:receive str_num = %s\n" , str_num);
	}
	int ret = (int)strtol( str_num, NULL, 10 );
	free(str_hello);
	free(str_num);
	return ret;
}

int pack_str( char *str , int index )
{
	char *str_index = (char *)malloc(SIZE);
	sprintf( str_index, "%d", index);
	char *str_ok = STR_OK;
	sprintf( str, "%s%s", str_ok, str_index );
	printf("service:res = %s\n" , str);
	free(str_index);
	return 1;
}

客户端程序:

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

#define PORT (1234)
#define SIZE (16)
#define STR_HELLO "Hello"

int create_listen_socket();
int pack_str( char *str );

int main()
{

	int connect_socket = create_listen_socket();

	while(1)
	{
		char msg[SIZE];
		pack_str(msg);
		int ret = write( connect_socket , msg , SIZE );
		if(ret == -1)
		{
			perror("write");
		}
		ret = read( connect_socket , msg , SIZE );
		if(ret == -1)
		{
			perror("read");
			close(connect_socket);
			exit(1);
		}
		if(ret > 0)
		{
			printf("client:read ret = %s\n" , msg);
		}
		sleep(1);
	}
	close(connect_socket);
	return 0;
}

int create_listen_socket()
{
	int service_socket = socket( AF_INET, SOCK_STREAM, 0 );
	if( service_socket == -1 )
	{
		perror("socket");
		return -1;
	}
	struct sockaddr_in addr;
	memset( &addr, 0, sizeof(addr) );
	addr.sin_family = AF_INET;
	addr.sin_port   = htons(PORT);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
	inet_aton( "127.0.0.1", &(addr.sin_addr) );

	int addrlen = sizeof(addr);
	int ret = connect( service_socket, (struct sockaddr *)(&addr), addrlen );
	if(ret == -1)
	{
		perror("connect");
		return -1;
	}
	
	printf("client:connect to a service\n");
	return service_socket;
}

int pack_str( char *str )
{
	char *str_hello = STR_HELLO;
	int len = sizeof(str_hello);
	int index = rand() % 10;
	char str_index[SIZE];
	sprintf( str_index, "%d", index);
	sprintf( str, "%s%s", str_hello, str_index );
	printf("client:str = %s\n" , str);
	return 1;
}

现在的代码是修正过的代码。编写过程中出现过SIGPIPE错误,导致程序异常退出

原因是服务端的代码close socket写到了while里,导致第一次通信结束后,socket被关闭,但客户端还在发数据,发不通,报错。

详细解释参照http://blog.sina.com.cn/s/blog_4888f88101016xr9.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值