记录(只在此设计中有效):
1,实现TCP服务端时,在客户端连接中断后,支持客户端重新连接。此处我用的死goto,让程序跳回准握手阶段;
2,通过recv返回值为0或-1,判断,socket断开连接,这种做法应该是不合理的。但在此处,我不会发送信号,故可作为简单的判断依据。
3,服务端可以不配置客户端ip,以支持不同设备的连接。在客户端需要配置客户端ip和服务端IP;
4,此处我只用recv做socket断开的判断依据,然后用pthread_cancel强制关闭发送线程。
服务端代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
void network_send(void *arg);
void network_recv(void *arg);
//pass parameters to the thread function
typedef struct{
int para1;
}str_para;
//--------------------------------------------------------------------
//*****************recvice*************************************
void network_recv(void *arg)
{
int recv_len;
char rx_buff[99];
int rx_buff_len=0;
str_para *sockfd;
sockfd=arg;
printf("recv_sockfd=%d\n",sockfd->para1);
while(1)
{
memset(rx_buff,0,98);
recv_len=recv(sockfd->para1,rx_buff,98,0);//recvice socket data
if(recv_len<=0)
{
// printf("service disconnect !!\n");
break;
}
else
{
rx_buff_len=strlen(rx_buff);
printf("rx_buff_len=%d, rx_data: %s",rx_buff_len,rx_buff);
if(rx_buff[rx_buff_len-1]!='\n')
printf("\n");
}
}
printf("recv pthread finish \n");
pthread_exit(NULL);
}
//----------------------------------------------------------
//*******************send***************************************
void network_send(void *arg)
{
char tx_buff[99];
int tx_buff_len=0;
str_para *sockfd;
sockfd=arg;
printf("send_sockfd=%d\n",sockfd->para1);
while(1)
{
memset(tx_buff,0,99);
printf("send data: ");
fgets(tx_buff,99,stdin);
tx_buff_len=strlen(tx_buff);
// printf("tx_buff_len=%d,tx_buff: %s",tx_buff_len,tx_buff);
send(sockfd->para1,tx_buff,tx_buff_len,0);
}
printf("pthread_send finish!!!\n");
pthread_exit(NULL);
}
//--------------------------------------------------------------
//**************************************************************
int main()
{
// int cli_port=0;
// char cli_ip[19];
int ser_port=0;
char ser_ip[19];
struct sockaddr_in ser_addr;
struct sockaddr_in cli_addr;
socklen_t ser_addr_size=0;
socklen_t cli_addr_size=0;
str_para pthread_para;
pthread_t send_pthread;
pthread_t recv_pthread;
int send_pthread_create_status;
int recv_pthread_create_status;
int recv_pthread_status;
int send_pthread_status;
int sockfd=0;//socket descriptor
int bind_status=0;
int listen_status=0;
int aptfd=0;//create cliten connection
int recv_len=0;
char buff[99];
int buff_len=0;
int run_config=0;
//***********************************************************************
//input target addr
printf("input service port and ip :(format:ip port) \n");
printf("input:");
scanf("%s%d",ser_ip, &ser_port);
do
{
}while(getchar()!='\n');
printf("service ip port : %s %d\n",ser_ip,ser_port);
ser_addr.sin_family=AF_INET; //protocol
ser_addr.sin_port=htons(ser_port);//port
ser_addr.sin_addr.s_addr=inet_addr(ser_ip);//ip
ser_addr_size=sizeof(ser_addr);
cli_addr.sin_family=AF_INET; //protocol
cli_addr.sin_port=htons(0);//port
cli_addr.sin_addr.s_addr=inet_addr("0.0.0.0");//ip
cli_addr_size=sizeof(cli_addr);
//----------------------------------------------------------------------
//create udp socket
sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sockfd==-1)
{
printf("socket=%d create failed!!\n",sockfd);
}
else
{
printf("socket=%d create successed!!\n",sockfd);
}
//bind local port/IP
bind_status=bind(sockfd,(struct sockaddr*)&ser_addr,ser_addr_size);
if(bind_status==-1)
{
printf("bind failed!\n");
}
else
{
printf("bind successed!!!\n");
}
CONNET:
//listen socket
listen_status=listen(sockfd,9);
if(listen_status!=0)
{
printf("listen error!!!\n");
}
else
{
printf("listen successed!!!\n");
}
//create connect and client device
aptfd=accept(sockfd,(struct sockaddr*)&cli_addr,&cli_addr_size);
printf("cliten ip : %s\n",inet_ntoa(cli_addr.sin_addr));
printf("aptfd=%d\n",aptfd);
//---------------------------------------------------------------------
pthread_para.para1=aptfd;
//create send udp data pthread
send_pthread_create_status=pthread_create(&send_pthread,NULL,(void *)network_send,&pthread_para);
if(send_pthread_create_status!=0)
{
printf("send_pthread create failed!!\n");
}
//create recv udp data pthread
recv_pthread_create_status=pthread_create(&recv_pthread,NULL,(void *)network_recv,&pthread_para);
if(recv_pthread_create_status!=0)
{
printf("recv_pthread create failed!!\n");
}
recv_pthread_status=pthread_join(recv_pthread,NULL);
printf("sssssss\n");
if(recv_pthread_status==0)
pthread_cancel(send_pthread);
send_pthread_status=pthread_join(send_pthread,NULL);
if(send_pthread_status==0)
{
printf("client deveice disconnect!!!! restart connect : \n");
goto CONNET;
}
printf("bye bye!!\n");
shutdown(sockfd,2);
return 0;
}
客户端代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
void network_send(void *arg);
void network_recv(void *arg);
//pass parameters to the thread function
typedef struct{
int para1;
}str_para;
//--------------------------------------------------------------------
//*****************recvice*************************************
void network_recv(void *arg)
{
int recv_len;
char rx_buff[99];
int rx_buff_len=0;
str_para *sockfd;
sockfd=arg;
printf("recv_sockfd=%d\n",sockfd->para1);
while(1)
{
memset(rx_buff,0,98);
recv_len=recv(sockfd->para1,rx_buff,98,0);//recvice socket data
if(recv_len<=0)
{
// printf("service disconnect !!\n");
break;
}
else
{
rx_buff_len=strlen(rx_buff);
printf("rx_buff_len=%d, rx_data: %s",rx_buff_len,rx_buff);
if(rx_buff[rx_buff_len-1]!='\n')
printf("\n");
}
}
printf("recv pthread finish \n");
pthread_exit(NULL);
}
//----------------------------------------------------------
//*******************send***************************************
void network_send(void *arg)
{
char tx_buff[99];
int tx_buff_len=0;
str_para *sockfd;
sockfd=arg;
printf("send_sockfd=%d\n",sockfd->para1);
while(1)
{
memset(tx_buff,0,99);
printf("send data: ");
fgets(tx_buff,99,stdin);
tx_buff_len=strlen(tx_buff);
// printf("tx_buff_len=%d,tx_buff: %s",tx_buff_len,tx_buff);
send(sockfd->para1,tx_buff,tx_buff_len,0);
}
printf("pthread_send finish!!!\n");
pthread_exit(NULL);
}
//--------------------------------------------------------------
//**************************************************************
int main()
{
int cli_port=0;
char cli_ip[19];
int ser_port=0;
char ser_ip[19];
struct sockaddr_in ser_addr;
struct sockaddr_in cli_addr;
socklen_t ser_addr_size=0;
socklen_t cli_addr_size=0;
str_para pthread_para;
pthread_t send_pthread;
pthread_t recv_pthread;
int send_pthread_create_status;
int recv_pthread_create_status;
int recv_pthread_status;
int send_pthread_status;
int sockfd=0;//socket descriptor
int bind_status=0;
int connect_status; //create service connection
int recv_len=0;
char buff[99];
int buff_len=0;
int run_config=0;
//***********************************************************************
//input target addr
printf("input service port and ip :(format:ip port) \n");
printf("input:");
scanf("%s%d",ser_ip, &ser_port);
do
{
}while(getchar()!='\n');
printf("input cliten port and ip:(format: port ip)\n");
printf("input: ");
scanf("%s%d",cli_ip, &cli_port);
do
{
}while(getchar()!='\n');
printf("service ip port : %s %d\n",ser_ip,ser_port);
printf("cliten ip port: %s %d\n",cli_ip,cli_port);
ser_addr.sin_family=AF_INET; //protocol
ser_addr.sin_port=htons(ser_port);//port
ser_addr.sin_addr.s_addr=inet_addr(ser_ip);//ip
ser_addr_size=sizeof(ser_addr);
cli_addr.sin_family=AF_INET; //protocol
cli_addr.sin_port=htons(cli_port);//port
cli_addr.sin_addr.s_addr=inet_addr(cli_ip);//ip
cli_addr_size=sizeof(cli_addr);
//----------------------------------------------------------------------
//create udp socket
sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sockfd==-1)
{
printf("socket=%d create failed!!\n",sockfd);
}
else
{
printf("socket=%d create successed!!\n",sockfd);
}
//bind local port/IP
bind_status=bind(sockfd,(struct sockaddr*)&cli_addr,cli_addr_size);
if(bind_status==-1)
{
printf("bind failed!\n");
}
else
{
printf("bind successed!!!\n");
}
//create connect
connect_status=connect(sockfd,(struct sockaddr*)&ser_addr,ser_addr_size);
if(connect_status==-1)
{
printf("connect service failed!!\n");
}
else
{
printf("connect service successed!!\n");
}
//---------------------------------------------------------------------
pthread_para.para1=sockfd;
//create send udp data pthread
send_pthread_create_status=pthread_create(&send_pthread,NULL,(void *)network_send,&pthread_para);
if(send_pthread_create_status!=0)
{
printf("send_pthread create failed!!\n");
}
//create recv udp data pthread
recv_pthread_create_status=pthread_create(&recv_pthread,NULL,(void *)network_recv,&pthread_para);
if(recv_pthread_create_status!=0)
{
printf("recv_pthread create failed!!\n");
}
recv_pthread_status=pthread_join(recv_pthread,NULL);
if(recv_pthread_status==0)
{
pthread_cancel(send_pthread);
}
send_pthread_status=pthread_join(send_pthread,NULL);
if(send_pthread_status==0)
{
printf("service deveice disconnect!!!! \n");
}
printf("bye bye!!!\n");
shutdown(sockfd,2);
return 0;
}