编辑:以下代码已经修复,可以正确接收和发送,并记录发送和收到的邮件的实际字节数(后者归功于EJP)
我正在用Unix编写C语言。
我有服务器和客户端应该交换消息。虽然客户端似乎发送消息很好,但服务器不会收到客户端发送的消息。我已经尝试过使用recv()
和read()
(我知道它们实际上是相同的,但recv()
上有额外的标志)但我没有运气,我不确定是什么问题确实是。
我在每次发送邮件后都将sleep(3)
放在客户端代码中但我看到一旦客户端和服务器连接,服务器会立即关闭,而不会等待传入的邮件。我做错了什么?
这是客户端代码:
#define SERVER_TCP_PORT 11112
#define MAX_DATA_SIZE 500
int main(int argc, char * argv[])
{
int sockfd;
char * host;
char msg[MAX_DATA_SIZE];/* = "get my msg!\n";*/
int msg_len;
struct hostent * hp;
struct sockaddr_in client_address, server_address;
printf("y halo thar\n");
// looking up from the host database
if (argc == 2)
host = argv[1];
else
exit(1);
printf("sdf\n");
hp = gethostbyname(host);
if (!hp)
exit(1);
printf("host found\n");
// setting up address and port structure information
bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string
server_address.sin_family = AF_INET;
bcopy(hp->h_addr, (char *) &server_address.sin_addr, hp->h_length);
server_address.sin_port = htons(SERVER_TCP_PORT);
printf("set\n");
// opening up socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
exit(1);
printf("opened\n");
// connecting
if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
exit(1);
printf("connected\n");
int i;
for (i = 0; i < MAX_DATA_SIZE; ++i)
{
msg[i] = '.';
}
msg[MAX_DATA_SIZE-1] = '\0';
for(i = 0; i < 11; i++)
{
// send message to connected socket
msg_len = write(sockfd, msg, MAX_DATA_SIZE);
if(msg_len < 1)
printf("notsent\n");
else
printf("%i bytes sent\n", msg_len);
// recieve messages from connected socket
msg_len = read(sockfd, msg, MAX_DATA_SIZE);
if (msg_len < 1)
printf("not recieved\n");
else
{
printf("%i bytes received\n", msg_len);
printf(msg);
printf("\n");
}
}
// close connection
close(sockfd);
printf("closed\n");
}
这是服务器端
#define SERVER_TCP_PORT 11112
#define MAX_DATA_SIZE 500
int main()
{
printf("o halo thar\n");
int sockfd, new_sockfd;
int client_addr_len;
char msg [MAX_DATA_SIZE];
int msg_len;
char got_msg [11] = "got ur msg\0";
struct sockaddr_in server_address, client_address;
// setting up address and port structure information
bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(SERVER_TCP_PORT);
// opening up socket
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
exit(1);
printf("socket is opened\n");
// binding
if (bind(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0)
exit(1);
printf("socket is bound\n");
// listening
listen(sockfd,5);
printf("listening\n");
// block and wait for an incoming connection
client_addr_len = sizeof(client_address);
new_sockfd = accept(sockfd, (struct sockaddr *) &client_address, &client_addr_len);
if (new_sockfd < 0)
exit(1);
printf("accepted\n");
int i;
for( i = 0; i < 11; i++)
{
// recieve messages from connected socket
printf("waiting\n");
msg_len = read(new_sockfd, msg, MAX_DATA_SIZE);
if (msg_len < 1)
{
printf("no msg recieved\n");
}
else
{
printf("bytes recieved: %i\n", msg_len);
}
// send message to connected socket
msg_len = write(new_sockfd, got_msg, sizeof(got_msg));
if (msg_len < 1)
printf("not sent\n");
else
printf("%i bytes sent\n", msg_len);
}
// close connection
close(sockfd);
printf("socket closed. BYE! \n");
}
答案 0 :(得分:9)
在服务器代码中,问题出现在这一行:
msg_len = read(sockfd, msg, MAX_DATA_SIZE);
您在read
上呼叫sockfd
,但您需要在read
(recv
返回的套接字上呼叫new_sockfd
或accept()
)。 new_sockfd
是连接到客户端的sockfd
({{1}}用于接受进一步的连接 - 例如,如果另一个客户端连接)。
答案 1 :(得分:0)
您应该从accept
返回的套接字中读取。
尝试致电从read
返回的socket
上的accept
。
答案 2 :(得分:0)
发送方:
while(!feof(fp))
{
len=fread(buff,sizeof(char),MW,fp);
if(len==0)
{
//EOF
st=write(cd,&d,sizeof(int));
break;
}
else
{
st=write(cd,buff,len);
}
}
答案 3 :(得分:0)
接收方:
while(1)
{
len=read(sd,buff,sizeof(buff));
if(len==0)
{
//End of File receving.
break;
}
else
{
st=fwrite(buff,sizeof(char),len,fp);
}
}
答案 4 :(得分:-2)
是基于流或数据报的实现吗?
您的操作流程存在一些问题。在客户端发送任何内容之前,服务器可能会开始读取。
由于客户端和服务器是分开的,您可以想象它们是并发运行的。 在服务器端“接受”连接请求之后,可能会出现一些握手开销或网络延迟导致服务器应用程序提前执行,尝试提取数据但遇到错误(尚未收到数据)。 您可以通过在接受连接后在服务器代码中添加sleep来尝试此操作,其中客户端应该有足够的时间来发送数据。
另一个更好的解决方案是使数据检索处理空缓冲区或异步读取。