题目要求:
1、服务端会建立socket,绑定socket,等待客户端的连接
2、客户端会建立socket,与服务端连接,若连接成功,就会把str字符串传给服务端,str字符串的内容是:“商品号,商品名,价格”的格式,如“A001 电视机 20000”
3、服务端若接受客户端的连接,会读取客户端传送过来的字符串,并解释字符串的内容,算出价格的含税价,再将处理后的字符串回传给客户端
4、客户端收到服务端的回传信息,会将信息显示在显示器上
注释一下:
1、有关strtok()
头文件:#include <string.h>
定义函数:char * strtok(char *s, const char *delim);
函数说明:strtok()用来将字符串分割成一个个片段。参数s 指向欲分割的字符串,参数delim 则为分割字符串,当strtok()在参数s 的字符串中发现到参数delim 的分割字符时则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s 字符串,往后的调用则将参数s 设置成NULL。每次调用成功则返回下一个分割后的字符串指针。
返回值:返回下一个分割后的字符串指针,如果已无从分割则返回NULL。
2、服务端的一条命令:sin.sin_addr.s_adddr=htonl(INADDR_ANY);
它的意义是:让服务端的socket可以接受同一个局域网内所有IP地址,INADDR_ANY可视为通配符,同样的,要让socket接受同一个局域网内所有port number,则输入命令:
sin.sin_addr.s_adddr=htons(0);
3、命令行自变量int main(int argc,char *argv[])
这个功能可以让程序在运行时,接受由用户输入的一些字符串,作为主程序的参数,其中第一个自变量argc会保存用户输入的字符串个数,第二个自变量argv[]是字符串指针数组,指向用户所输入的字符串的内容
如果在客户端执行时输入如下字符串:
./client "A002 音响 15000"
此时,自变量argc的值为2,自变量argv[0]的内容为client, argv[1]的内容为A002 音响 15000
代码部分:
服务端:
/*server.c*/
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
int port=8000;
int main()
{
struct sockaddr_in sin;
struct sockaddr_in pin;
int mysock;
int tempsock;
int addrsize;
char str[100],str1[20],str2[20],str3[20];
char buf[100];
int i,len1,len2;
float c;
//建立socket
mysock=socket(AF_INET,SOCK_STREAM,0);
if(mysock==-1)//表示无法定位
{
perror("call to socket");
exit(1);
}
//建立IPV4地址
bzero(&sin,sizeof(sin));
sin.sin_family=AF_INET;
sin.sin_addr.s_adddr=htonl(INADDR_ANY);
sin.sin_port=htons(port);
//绑定socket
if(bind(mysock,(struct sockaddr *)&sin,sizeof(sin))==-1)
{
perror("call to bind");
exit(1);
}
//监听客户端
if(listen(mysock,20)==-1)
{
perror("call to listen");
exit(1);
}
printf("ACCEPTing connections");
while(1)
{
//接受来自客户端的连接
tempsock=accept(mysock,(struct sockaddr *)&pin,sizeof(pin))==-1)
if(tempsock==-1)
{
perror("call to accept");
exit(1);
}
//接受来自客户端的信息
len1=recv(tempsock,str,100,0);
printf("\n收到字符数%d\n",len1);
str[len1]=0;
printf("reccived from client:%s\n",str);
//分析处理客户端传来的信息
if(len1>0)
{
strcpy(str1,strtok(str," "));
printf("第一个字符串为:%s\n",str1);
strcpy(str2,strtok(NULL," "));
printf("第二个字符串为:%s\n",str2);
strcpy(str3,strtok(NULL," "));
printf("第三个字符串为:%s\n",str3);
c=atof(str3)*1.05;
sprintf(buf,"商 品 号 为 %s \n 商 品 名 为 %s\n 含 税 价 为:%.2f\n",str1,str2,c);
}
//将处理过的信息返回给客户端
len2=strlen(buf);
if(send(temosock,buf,len2,0)==-1)
{
perror("call to send");
exit(1);
}
//关闭与client端的连接
close(tempsock);
}
return 0;
}
客户端
/*client.c*/
#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
int port=8000;
int main(int argc,char *argv[])
{
struct sockaddr_in pin;
int mysock;
char *str="A001 电视机 20000";
char buf[8192];
if(argv<2)
{
printf("使用方法:Client字符串\n使用默认字符串");
}
else
{
str=argv[1];
}
//建立socket
mysock=socket(AF_INET,SOCK_STREAM,0);
if(mysock==-1)//表示无法定位
{
perror("call to socket");
exit(1);
}
//建立IPV4地址
bzero(&pin,sizeof(pin));
pin.sin_family=AF_INET;
pin.sin_addr.s_adddr=inet_addr("192.168.1.20");
pin.sin_port=htons(port);
//连接服务端
if(connect(mysock,(void *)&pin,sizeof(pin))==-1)
{
perror("call to connect");
exit(1);
}
//将str字符串传给服务端
printf("sending message %s to server...\n",str);
if(send(mysock,str,strlen(syr),0)==-1)
{
perror("call to send\n");
exit(1);
}
//接受服务端的回传信息
if(recv(mysock,buf,8192,0)==-1)
{
perror("call to recev");
exit(1);
}
printf("\nresponse from server:\n \n %s \n",buf);
//关闭与服务端的连接
close(tempsock);
}
return 0;
}
操作方法:
1、Linux系统
2、先运行服务端,它会等客户端的连接
3、在另一个终端机窗口中运行客户端,它会使用默认字符串,把str传送给服务端,并接受服务端的回传信息,同时在服务端的窗口会显示客户端传来的字符串
4、当然也可以在客户端输入要传入服务端的字符串