在看完Linux程序设计中关于socket套接字这一章套接字的通信流程的介绍后,自己写了客户端和服务器端的程序。发现了一些需要注意的问题。
客户端:
套接字Internet地址s_addr不能直接用127.0.0.1或者是这个字符串“127.0.0.1”来赋值,而是应该使用inet_addr("127.0.0.1").
在connect函数中,address_len不应该直接写数字,比如4,而是应该用sizeof(address) ,这里的address是套接字地址,struct sockaddr_in类型。
connect函数中的address不能直接用sockaddr_in类型变量的地址,而是应该将这个地址加一个(struct sockaddr*)强制类型转换
write函数中的三个参数,而不是直接一个字符串。三个参数分别为客户端套接字,第二个为要发送的数据的缓存地址,后面一个数据长度,直接用数字。
close()中应该有一个参数,为套接字。
socket函数中第三个参数应该写上,默认为0。
socket函数返回的是一个int类型的描述符,最好不要用它来判断套接字是否创建成功。
#include<sys/socket.h> #include<netinet/in.h> #include<stdio.h> //下面三行头文件可不引入 #include<sys/types.h> #include<arpa/inet.h> #include<unistd.h> int main() { //char *buff; int serversoc=socket(AF_INET,SOCK_STREAM,0),clientsoc; struct sockaddr_in address,clientaddress; address.sin_family=AF_INET; address.sin_port=9734; address.sin_addr.s_addr=inet_addr("127.0.0.1"); if(bind(serversoc,(struct sockaddr*)&address,sizeof(address))==-1) { printf("bind fail!"); return -1; } if(listen(serversoc,8)==-1) { printf("listen fail!"); return -1; } size_t client_addr_len=sizeof(address); int len=sizeof(clientaddress); while(1) { char ch; clientsoc=accept(serversoc,(struct sockaddr*)&clientaddress,(socklen_t *__restrict)&len); read(clientsoc,&ch,1); printf("data from client:%c\n",ch); //ch++; //write(clientsoc,&ch,1); close(clientsoc); } return 0; }
服务器端:
read()函数中的第一个参数为客户端的描述符,而不是服务器端的描述符。
accept()函数的第三个参数应该是客户端的地址长度的指针,不能用&sizeof(address)作实参,sizeof返回对象等,应该用int len=sizeof(address); 然后实参&len。并且在&len之前要加上(socklen_t *__restrict)进行强制转换。
accept()函数的第二个参数是客户端的address指针,不是服务器的address指针。且要进行类型转换。
在close()中的描述符是由accept返回的客户端描述符,而不是服务器描述符。
accept()和read()应该放在while中。循环接收和读取
#include<sys/socket.h> #include<netinet/in.h> #include<stdio.h> //下面三行头文件可不引入 #include<sys/types.h> #include<arpa/inet.h> #include<unistd.h> int main() { char ch='a'; int clientsoc=socket(AF_INET,SOCK_STREAM,0); struct sockaddr_in address; address.sin_family=AF_INET; address.sin_port=9734; address.sin_addr.s_addr=inet_addr("127.0.0.1"); int connec=connect(clientsoc,(struct sockaddr*)&address,sizeof(address)); if(connec==-1){printf("connection fail");return -1;} write(clientsoc,&ch,1); //read(clientsoc,&ch,1); //printf("data from server:%c\n",ch); close(clientsoc); return 0; }
如果不是在在同一台机器上,还要修改IP等。
注意:我发现一个特别搞笑但也特别值得深思的问题——在服务器端的输出中的\n不能省略,否则看不到数据。
另外一个有趣的事情是,将char类型换成char*后,相应输出修改后,有和没有\n也有差别,此时将\n换成空格也没有数据显示在服务器上。为什么呢?值得深思!