我正在尝试在C中开发一个应用程序来接收消息并通过TCP发送它。为此,我使用了2个线程:要侦听的服务器线程和发送它的客户端线程。
这里是服务器和主要功能:
void dostuff(int sock)
{
int n;
char buffer[256];
bzero(buffer,256);
n = read(sock,buffer,255);
if (n < 0) error("ERROR reading from socket");
else {
pthread_t t_tcp_client;
pthread_create(&t_tcp_client, NULL, tcp_client, buffer);
}
n = write(sock,"Message received",18);
if (n < 0) error("ERROR writing to socket");
}
static void *tcp_server(void *p_data)
{
int sockfd, newsockfd, pid;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(TCP_PORT);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) error("ERROR on accept");
pid = fork();
if (pid < 0) error("ERROR on fork");
if (pid == 0) {
close(sockfd);
dostuff(newsockfd);
exit(0);
} else {
close(newsockfd);
}
}
close(sockfd);
return 0;
}
int main (void)
{
pthread_t t_tcp_server;
pthread_create(&t_tcp_server, NULL, tcp_server, NULL);
pthread_join(t_tcp_server, NULL);
return 0;
}
客户端线程:
static void *tcp_client(void *p_data)
{
if (p_data != NULL)
{
char const *message = p_data;
printf("Message transmitted : %s\n", message);
}
return 0;
}
问题是客户端线程没有收到好的char,结果是:
发送的消息:???〜?
我认为这个问题来自于:n = read(sock,buffer,255);但我真的不明白为什么。
感谢您的帮助
答案 0 :(得分:1)
do_stuff
很可能在客户端线程完成它之前退出。
客户端线程使用堆栈分配的内存,然后在do_stuff
退出时释放,并将被其他代码重用。
解决此问题的方法是将堆分配的内存传递给客户端。如果动态分配后者,则需要在客户端完成其工作后释放它。
答案 1 :(得分:1)
static char buffer[256];
void dostuff(int sock)
{
int n;
bzero(buffer,256);
n = read(sock,buffer,255);
...
}
使用套接字时要小心,一次阅读可能无法提供您等待的全部信息。
对于结构化消息,您定义的协议(您应该很好地定义它)必须首先提供消息标识符,并且在读取sizeof(theSpecificMessage)之前读取,特定消息由标识符标识。