1.服务器采用简易线程开启,将传送过来的字母转换为大写再发送过去,如果传送过来的第一个字符为@则退出
2.客户端循环读入,如果输入@则退出当前socket
服务器程序:server_thread.c
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<sys/un.h>
#include<sys/wait.h>
#include<signal.h>
#include<pthread.h>
void* thr_fn(void* arg)
{
int n_read;
char sz_buff[1024];
int n_newfd = *((int*)arg);
int j;
printf("new socket: %d\n",n_newfd);
//从客户端读取数据
while( ( n_read=read(n_newfd,sz_buff,1024) ) > 0 )
{
if(sz_buff[0]=='@')
{
printf("socket(%d) out ...\n", n_newfd);
close(n_newfd);
break;
}
printf("read %d byte data from client:%s",n_read,sz_buff);
//将读取的数据全部转换为大写
for(j=0; j<n_read; j++)
{
sz_buff[j]=toupper(sz_buff[j]);
}
//将转换后的字符串再发送出去
if(write(n_newfd,sz_buff,n_read)==-1)
{
fprintf(stderr,"write data error: %s\n", strerror(errno));
exit(1);
}
memset(sz_buff,0,1024);
}
close(n_newfd);
return 0;
}
int main(int argc,char* argv[])
{
int n_sockfd, n_newfd;
struct sockaddr_in st_server;
struct sockaddr_in st_client;
int n_client_size,n_read_size;
socklen_t n_addr_len;
int n_port;
char sz_buff[1024];
pthread_t pid;
if(argc != 2)
{
printf("please input argument\n");
exit(1);
}
if( (n_sockfd=socket(PF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"scoket error:%s\n",strerror(errno));
exit(1);
}
//bzero(&st_server,sizeof(st_server));
memset(&st_server,0,sizeof(st_server));
st_server.sin_family=AF_INET;
st_server.sin_addr.s_addr=htonl(INADDR_ANY);
st_server.sin_port=htons( atoi(argv[1]) );
if(bind(n_sockfd,(struct sockaddr*)&st_server,sizeof(st_server))==-1)
{
fprintf(stderr,"bind server error:%s\n\a",strerror(errno));
close(n_sockfd);
exit(1);
}
if(listen(n_sockfd,2)==-1)
{
fprintf(stderr,"listen error:%s\n\a",strerror(errno));
close(n_sockfd);
exit(1);
}
while(1)
{
n_client_size=sizeof(st_client);
if( (n_newfd=accept(n_sockfd,(struct sockaddr*)&st_client,&n_client_size))==-1)
{
if(errno==EINTR)
{
continue;
}
fprintf(stderr,"accept error:%s\n\a",strerror(errno));
close(n_sockfd);
exit(1);
}
fprintf(stderr,"server get connet from:%s\n",inet_ntoa(st_client.sin_addr));
printf("new socket: %d\n",n_newfd);
//创建线程
if( (pthread_create(&pid,NULL,thr_fn,&n_newfd))==-1)
{
fprintf(stderr,"create thread error:%s\n",strerror(errno));
close(n_newfd);
close(n_sockfd);
exit(1);
}
}
//close(n_sockfd);
exit(0);
}
客户端程序:client_thread.c
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/un.h>
#include<unistd.h>
#define PORT_NUM 3333
int main(int argc,char*argv[])
{
int n_sockfd;
struct sockaddr_in st_server;
char sz_buff[1024];
struct hostent* pst_host;
int n_port;
int n_read;
if(argc != 3)
{
fprintf(stderr,"please input argument\n");
exit(1);
}
/*
if( (pst_host=gethostbyname(argv[1]))==NULL)
{
fprintf(stderr,"gethostname error:%s\n",strerror(errno));
exit(1);
}
*/
if( (n_sockfd=socket(PF_INET,SOCK_STREAM,0))==-1)
{
fprintf(stderr,"scoket error:%s\n",strerror(errno));
exit(1);
}
//bzero(&st_server,sizeof(st_server));
memset(&st_server,0,sizeof(st_server));
st_server.sin_family=AF_INET;
//st_server.sin_addr=*((struct in_addr*)pst_host->h_addr);
//pst_host 是一个指针指向in_addr*类型的数组
st_server.sin_addr.s_addr=inet_addr(argv[1]);
st_server.sin_port=htons(atoi(argv[2]));
if(connect(n_sockfd,(struct sockaddr*)&st_server,sizeof(st_server))==-1)
{
fprintf(stderr,"connect server error:%s\n\a",strerror(errno));
close(n_sockfd);
exit(1);
}
while(1)
{
//输入数据提示
if( write(STDOUT_FILENO,"\nplease input data:",20)==-1)
{
fprintf(stderr,"write error:%s\n",strerror(errno));
exit(1);
}
//读取输入的数据,并发送给服务器
memset(sz_buff,0,1024);
n_read=read(STDIN_FILENO,sz_buff,1024);
printf("n_read = %d,send message: %s",n_read,sz_buff);
if(n_read>0)
{
if( write(n_sockfd,sz_buff,n_read)==-1)
{
fprintf(stderr,"write error:%s\n",strerror(errno));
exit(1);
}
}
//如果读取的第一个数据位@则推出循环
if( sz_buff[0]=='@' )
{
break;
}
//从服务器读取数据
memset(sz_buff,0,1024);
printf("n_sockfd = %d\n",n_sockfd);
n_read=read(n_sockfd,sz_buff,n_read);
printf("read message: %s",sz_buff);
if(n_read>0)
{
printf("get message from server: %s",sz_buff);
}
}
close(n_sockfd);
exit(0);
}
调式结果:
注:切记不要在服务器段提前关闭socket,服务器监听套接字不能关闭,一直处于循环等待中
一旦客户端关闭socket,就不能再发送数据了