我正在使用套接字编程制作服务器,这与客户对他说的话相呼应。但是当我打印出消息(由客户端发送)和它的长度时,消息和它的长度不匹配。我正在使用printf进行打印。
我基本上想要的是在客户端键入“exit”时关闭连接。但strcmp(“退出”,clientmessage)无效。
服务器代码:
//for running type ./a.out anyportnumber
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
void *function(void *s)
{
int s1;
int n;
char rmsg[500];
s1 = *(int *)s;
while((n = read(s1,rmsg,499)) > 0) {
rmsg[n] = '\0';
printf("%s %d\n",rmsg,strlen(rmsg));
bzero(rmsg,499);
}
pthread_exit(NULL);
}
int main(int arrc,char *argv[])
{
struct sockaddr_in server,client;
int s1,len;
int s2;
int n;
int i = 0;
int port;
pthread_t t1;
char message[500];
port = atoi(argv[1]);
bzero((char *)&server,sizeof(server));
server.sin_port = htons(port);
server.sin_addr.s_addr = INADDR_ANY;
server.sin_family = AF_INET;
s1 = socket(AF_INET,SOCK_STREAM,0);
if(s1 == -1) {
perror("socket not created\n");
exit(1);
}
if(bind(s1,(struct sockaddr *)&server,sizeof(struct sockaddr)) == -1) {
perror("socket not binded\n");
exit(1);
}
if(listen(s1,5) == -1) {
perror("unable to listen");
exit(1);
}
len = sizeof(struct sockaddr_in);
s2 = accept(s1,(struct sockaddr *)&client,&len);
pthread_create(&t1,NULL,function,(void *)&s2);
pthread_join(t1,NULL);
close(s2);
close(s1);
return 0;
}
客户端输入:
shivam@shivam-HP-Pavilion-15-Notebook-PC:~$ telnet localhost 8009
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hhh
jhiklmnop
服务器端输出:
shivam@shivam-HP-Pavilion-15-Notebook-PC:~/Study/chat$ ./a.out 8009
hhh
5
jhiklmnop
11
编辑代码:
//for running type ./a.out anyportnumber
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
void *function(void *s)
{
int s1;
int n;
char rmsg[500];
s1 = *(int *)s;
char d[] = {'e','x','i','t','\0'};
while((n = read(s1,rmsg,499)) > 0) {
rmsg[n-2] = '\0';
if(strcmp(d,rmsg) == 0) {
write(s1,"bye",3);
close(s1);
}
rmsg[n-2] = '\n';
rmsg[n-1] = '\0';
write(s1,rmsg,strlen(rmsg));
bzero(rmsg,499);
}
pthread_exit(NULL);
}
int main(int arrc,char *argv[])
{
struct sockaddr_in server,client;
int s1,len;
int s2;
int n;
int i = 0;
int port;
pthread_t t1;
char message[500];
port = atoi(argv[1]);
bzero((char *)&server,sizeof(server));
server.sin_port = htons(port);
server.sin_addr.s_addr = INADDR_ANY;
server.sin_family = AF_INET;
s1 = socket(AF_INET,SOCK_STREAM,0);
if(s1 == -1) {
perror("socket not created\n");
exit(1);
}
if(bind(s1,(struct sockaddr *)&server,sizeof(struct sockaddr)) == -1) {
perror("socket not binded\n");
exit(1);
}
if(listen(s1,5) == -1) {
perror("unable to listen");
exit(1);
}
len = sizeof(struct sockaddr_in);
s2 = accept(s1,(struct sockaddr *)&client,&len);
pthread_create(&t1,NULL,function,(void *)&s2);
pthread_join(t1,NULL);
close(s2);
close(s1);
return 0;
}
答案 0 :(得分:3)
TCP是面向流的协议,没有消息边界。因此,您无法编写依赖于read()
的返回值的应用程序逻辑。
这方面的解决方法是长度为前缀的字符串,或通过套接字发送NUL终止符。您也可以设想其他机制,但客户端必须在数据流中告诉服务器消息的结束位置; TCP层不会这样做。
答案 1 :(得分:0)
除了用户输入的字符外,当用户按下Enter键时,您还会得到回车符(0xd)和换行符(0xa)字符。这就是为什么你得到比你想象的更大的2号。