服务端程序:
#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被关闭,但客户端还在发数据,发不通,报错。