服务器在read()阻塞,客户端在write()阻塞,怎么回事?
刚开始学网络编程第一断代码就水了,很受打击啊。
服务端代码如下:
/*
============================================================================
Name : first_s.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
void my_fun(char * str) {
if(str == NULL)
return;
while(*str != '\0') {
if(*str > 'A' && * str < 'Z') {
*str = *str - 'A' + 'a';
}
}
return;
}
int main(void) {
struct sockaddr_in sin; //服务端socket
struct sockaddr_in cin;//客户端socket
int sfd;//socket文件描述符
int afd;//accept文件描述符
char buf[1024];//存储处理信息
char add_p[INET_ADDRSTRLEN]; //存储客户端地址的缓冲区
socklen_t len;
int n;
bzero(&sin,sizeof(struct sockaddr_in));
sin.sin_port = htons(8000);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd < 0) {
perror("socket建立失败。\n");
exit(1);
}
bind(sfd,(struct sockaddr *)&sin,sizeof(sin));
listen(sfd,10);
printf("waiting。。。。\n");
while(1) {
afd = accept(sfd,(struct sockaddr *)&sin,&len);
printf("。。。\n");
n = read(afd,buf,100); //就到这里阻塞了,怎么回事????????
printf("%d",n);
inet_ntop(AF_INET,&cin.sin_addr,add_p,INET_ADDRSTRLEN);
printf("客户端ip:%s,客户端端口:%d",add_p,ntohs(cin.sin_port));
my_fun(buf);
write(afd,buf,18);
close(afd);
}
if(close(sfd) == -1) {
perror("关闭失败。\n");
exit(1);
}
return EXIT_SUCCESS;
}
//客户端代码如下:
/*
============================================================================
Name : first_c.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main(void) {
struct sockaddr_in sin;
char buf[10240];
int sfd;
int port = 8000;
char *str = "Hello,I am Jimmy-Cao";
int res;
bzero(&sin,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port); //host -> network
inet_pton(AF_INET,"127.0.0.1",&sin.sin_addr); //from presentation (textual) to network (binary) format.
sfd = socket(AF_INET,SOCK_STREAM,0);
res = connect(sfd,(struct sockaddr *)&sin,sizeof(sin));
if(res < 0) {
perror("connect.\n");
exit(1);
}
write(sfd,str,strlen(str) + 1); //停在这一句?怎么回事啊????????????
read(sfd,buf,1024);
printf("读出信息:%s\n",buf);
return EXIT_SUCCESS;
}
[解决办法]
呵呵,你粗心了!小改了下,可以读写了。
#include <stdio.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
void my_fun(char * str)
{
int cnt = strlen(str);
if(str == NULL)
return;
while(0 < cnt)
{
if(((*str) > 'A') && ((* str) < 'Z'))
{
*str = *str - 'A' + 'a';
}
str++;
cnt--;
}
return;
}
int main(void)
{
struct sockaddr_in sin; //服务端socket
struct sockaddr_in cin;//客户端socket
int sfd; //socket文件描述符
int afd; //accept文件描述符
char buf[1024]; //存储处理信息
char add_p[INET_ADDRSTRLEN]; //存储客户端地址的缓冲区
socklen_t len;
int n;
bzero(&sin,sizeof(struct sockaddr_in));
sin.sin_port = htons(8000);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd < 0)
{
perror("socket建立失败。\n");
exit(1);
}
bind(sfd,(struct sockaddr *)&sin,sizeof(sin));
listen(sfd,10);
printf("waiting。。。。\n");
while(1)
{
afd = accept(sfd,(struct sockaddr *)&sin,&len);
printf("......\n");
n = read(afd,buf,100);
printf("%d\n",n);
printf("%s\n", buf);
inet_ntop(AF_INET,&cin.sin_addr,add_p,INET_ADDRSTRLEN);
printf("客户端ip:%s,客户端端口:%d\n",
add_p,ntohs(cin.sin_port));
my_fun(buf);
write(afd,buf,strlen(buf));
close(afd);
}
if(close(sfd) == -1)
{
perror("关闭失败。\n");
exit(1);
}
return EXIT_SUCCESS;
}
[解决办法]
先不说你这个程序的字符串处理程序,主要是这句出了问题afd = accept(sfd,(struct sockaddr *)&sin,&len);,你accept时覆盖了listen使用的socketaddr结构,应该是cin,然后len一般在实际使用时需要赋值的,一般是socklen_t len = sizeof(struct socketaddr);这样程序基本就可以正常运行了,当然先改改你那个字符串处理程序,你可以使用strerror(errno)来看一下你这个错误,会返回invalid argument 错误,另外这种网络程序最好使用无缓冲区的输出函数write,read这号的。照我说的改改就可以运行了