程序一
服务器端仅仅打印从客户端受到的字符串。客户端仅仅发一次字符串给服务器端。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERV_PORT 9527
//used to throw out an error
void sys_err(const char *str){
perror(str);
exit(1);
}
int main(){
int sfd = socket(PF_INET,SOCK_DGRAM,0);
//设定用户端的套接字地址
struct sockaddr_in serv_addr;//server socket address
serv_addr.sin_family = PF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//这个用来存储客户端的套接字信息,暂时是不知道的
struct sockaddr_in clnt_addr;//client socket address
socklen_t lgth_clnt_addr = sizeof(clnt_addr);
//缓冲
int rec = 0;
char buf[BUFSIZ];
//一些判断
if(sfd == -1){
sys_err("fail to create a socket!");
}
if((bind(sfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))) == -1){
sys_err("fail to bind a socket!");
}
//服务器真正执行的功能
while(1){
//wait until the arrival of any udp datagram
while((rec = recvfrom(sfd,(void *)buf,BUFSIZ,0,(struct sockaddr *)&clnt_addr,&lgth_clnt_addr)) == 0){
//这个函数的用处是接受从客户端来的数据,并且取得客户端的套接字地址。rec为-1时表明接收失败,0和正整数表明接受到的字符数目。sfd为服务器端某socket的文件描述符,buf是用于存放接受的字符串的数组,BUFSIZ是sizeof(buf),0这里是个形参flag(设成0就好),(struct sockaddr*)&clnt_addr是一个传出参数(别忘了前面的强制类型转换)存储客户端套接字的地址,&lgth_clnt_addr也是传出参数存放客户端套接字地址的长度。
}
//if any message, print it in the screen
write(STDOUT_FILENO,buf,rec);
}
//关闭套接字
close(sfd);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERV_PORT 9527
void sys_err(const char *str){
perror(str);
exit(1);
}
int main(){
int cfd = socket(PF_INET,SOCK_DGRAM,0);
struct sockaddr_in serv_addr;
serv_addr.sin_family = PF_INET;
serv_addr.sin_port = htons(SERV_PORT);
inet_pton(PF_INET,"127.0.0.1",&serv_addr.sin_addr.s_addr);
if(cfd == -1){
sys_err("fail to create a socket!");
}
// there is no need to bind for cfd --- it's automatic
char buf[] = "have fun!\n";
/*sendto函数用于向指定地址的套接字发送字符串。返回值-1表示失败,0或正整数表示发送的字符的数量。
cfd是客户端的某一socket的文件描述符,buf是所传输的字符串,sizeof(buf)是所传输的字符串的长度
serv_addr是接收方的套接字地址(勿忘强转),sizeof(serv_addr)为接收方套接字地址的长度(由于不是传出参数,所以和recvfrom的最后一个参数不同,不是指针),那个0是形参flag。*/
sendto(cfd,buf,sizeof(buf),0,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
return 0;
}
程序二?
在程序一的基础上进行修改,将其改为实现echo功能的UDP通信程序。(即客户端向服务器端发送一个字符,服务器接收这个字符后将其发给客户端)。
程序三
这是作业的要求。
?客户端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
void sys_err(const char *str){
}
double pow(double x,double y){
double result = 1;
result *= x;
}
return result;
short toShort(char *str,int length){
double number = 0;
int i = 1;
for(i = 1;i <= length;++i){
}
return (short) number;
}
/* char v[] = "9527";
printf("%lf\n",pow(2,3));
printf("%d\n",toShort(v,sizeof(v) - 1));
//argv[2]:server port argv[>=3]: data
// at least three arguments needed
if(argc < 3){
//firstly, print the server address
}
//network function
char* ipaddr = argv[1];
short port = toShort(argv[2],sizeof(argv[2] - 1));
int cfd = socket(PF_INET,SOCK_DGRAM,0);
struct sockaddr_in serv_addr;
serv_addr.sin_family = PF_INET;
serv_addr.sin_port = htons(port);
inet_pton(PF_INET,ipaddr,&serv_addr.sin_addr.s_addr);
if(cfd == -1){
sys_err("fail to create a socket!");
}
// there is no need to bind for cfd --- it's automatic
//the real function of the client
char **stringArray = argv;
int i = 3;
for(i=3;i < argc;++i){
sendto(cfd,*(stringArray + i),sizeof(stringArray[i]),0,(struct sockaddr *)&serv_addr,sizeof(serv_addr));
// printf("%s\n",*(stringArray + i));
}
return 0;
}
?服务器端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERV_PORT 9527
//used to joint two strings
char *strjoint(char* str1,int ls1,char* str2,int ls2){
//str1 as the input-output arguments, so it must have enough space
int i = 0;
for(i = ls1;;++i){
if(str2[i - ls1] == '\0'){
str1[i] = '\0';
break;
}
else{
str1[i] = str2[i - ls1];
}
}
return str1;
}
//used to throw out an error
void sys_err(const char *str){
perror(str);
exit(1);
}
int main(){
int sfd = socket(PF_INET,SOCK_DGRAM,0);
struct sockaddr_in serv_addr;//server socket address
serv_addr.sin_family = PF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
struct sockaddr_in clnt_addr;//client socket address
socklen_t lgth_clnt_addr = sizeof(clnt_addr);
int rec = 0;
char buf[BUFSIZ];
if(sfd == -1){
sys_err("fail to create a socket!");
}
if((bind(sfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr))) == -1){
sys_err("fail to bind a socket!");
}
/*//test for strjoit
char s1[] = "have"; char s2[] = " fun!";
printf("%s\n",strjoint(s1,sizeof(s1) - 1,s2,sizeof(s2) - 1));
*/
//the server real function
puts("./UDPserver: wait for data on port 9527");
while(1){
//wait until the arrival of any udp datagram
while((rec = recvfrom(sfd,(void *)buf,BUFSIZ,0,(struct sockaddr *)&clnt_addr,&lgth_clnt_addr)) == 0){
}
char ip[30]; inet_ntop(PF_INET,&clnt_addr.sin_addr.s_addr,ip,30);
printf("./UDPserver: ");
printf("from client <ip> = %s ",ip);
printf("<port> = %d",ntohs(clnt_addr.sin_port));
printf(" <content> = %s\n",buf);
// write(STDOUT_FILENO,buf,rec);
}
close(sfd);
return 0;
}
|