我们收到了这段代码,应该对其进行修改,以便无论何时客户端连接到服务器并发送消息,服务器都应该回复我听到了,伙计。这适用于一个或多个客户机,但下一个任务是,当新客户机连接时,服务器应该告诉所有其他已连接的客户机。
我以为这会很容易,但结果并不像我想象的那样。由于服务器总是得到sock 3,第一个客户端得到4,第二个客户端得到5等等,所以我尝试创建一个for循环,每当一个新客户端连接时,该循环就会向4,5发送消息,这使得服务器直接关闭自己。然后,我尝试在新客户端连接时,服务器应该向第一个客户端(4)发送消息,但前提是客户端(4)向他接收服务器发送的广播的服务器写入消息。
因此,客户似乎想写东西,但在收到服务器的广播之前需要写一些东西,任何帮助都将不胜感激,因为我们对所有这些都是初学者。
这就是代码目前的样子。
服务器C
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/times.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <pthread.h>
#define PORT 5555
#define MAXMSG 512
void *connection_handler(void *socket_desc)
{
int sock = *(int*)socket_desc;
int read_size;
char *message, client_message[2000], *message_to_client;
message = "Greetings! I am your connection handler\n";
write(sock, message, strlen(message));
while( (read_size = recv(sock, client_message, 2000, 0)) > 0)
{
client_message[read_size] = '\0';
printf("Client[%d]: %s", sock, client_message);
message_to_client = "I hear you dude...";
write(sock, message_to_client, 19);
memset(client_message, 0, 2000);
}
if(read_size == 0)
{
printf("Client[%d] disconnected", sock);
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
free(socket_desc);
return 0;
}
int makeSocket(unsigned short int port) {
int sock;
struct sockaddr_in name;
/* Create a socket. */
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock < 0) {
perror("Could not create a socket\n");
exit(EXIT_FAILURE);
}
name.sin_family = AF_INET;
name.sin_port = htons(port);
name.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) {
perror("Could not bind a name to the socket\n");
exit(EXIT_FAILURE);
}
return(sock);
}
int main(int argc, char *argv[])
{
int sock;
int clientSocket;
int i;
int *new_sock;
char *broadcast;
fd_set activeFdSet, readFdSet;
struct sockaddr_in clientName;
socklen_t size;
sock = makeSocket(PORT);
if(listen(sock,1) < 0)
{
perror("Could not listen for connections\n");
exit(EXIT_FAILURE);
}
FD_ZERO(&activeFdSet);
FD_SET(sock, &activeFdSet);
while(1)
{
printf("Waiting for connections\n");
readFdSet = activeFdSet;
if(select(FD_SETSIZE, &readFdSet, NULL, NULL, NULL) < 0)
{
perror("Select failed\n");
exit(EXIT_FAILURE);
}
for(i = 0; i < FD_SETSIZE; ++i)
{
if(FD_ISSET(i, &readFdSet))
{
if(i == sock)
{
size = sizeof(struct sockaddr_in);
pthread_t sniffer_thread;
while(( clientSocket = accept(sock, (struct sockaddr *)&clientName, (socklen_t *)&size)))
{
puts("Connection accepted");
new_sock = malloc(1);
*new_sock = clientSocket;
if( pthread_create( &sniffer_thread, NULL, connection_handler, (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
broadcast = "NEW CLIENT CONNECTED";
write(4, broadcast, sizeof(broadcast)); //just to see if when ever a new client connects the first client should get all these messages
write(4, broadcast, sizeof(broadcast));
write(4, broadcast, sizeof(broadcast));
pthread_detach(sniffer_thread);
puts("Handler assigned");
FD_SET(*new_sock, &activeFdSet);
}
if(clientSocket < 0)
{
perror("Could not accept connection\n");
exit(EXIT_FAILURE);
}
}
else
{
if(readMessageFromClient(i) < 0)
{
close(i);
FD_CLR(i, &activeFdSet);
}
}
}
}
}
}
对于客户端,代码如下所示
客户C
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define PORT 5555
#define hostNameLength 50
#define messageLength 256
void initSocketAddress(struct sockaddr_in *name, char *hostName, unsigned short int port)
{
struct hostent *hostInfo;
name->sin_family = AF_INET;
name->sin_port = htons(port);
hostInfo = gethostbyname(hostName);
if(hostInfo == NULL)
{
fprintf(stderr, "initSocketAddress - Unknown host %s\n",hostName);
exit(EXIT_FAILURE);
}
name->sin_addr = *(struct in_addr *)hostInfo->h_addr;
}
void writeMessage(int fileDescriptor, char *message)
{
int nOfBytes;
nOfBytes = write(fileDescriptor, message, strlen(message) + 1);
if(nOfBytes < 0)
{
perror("writeMessage - Could not write data\n");
exit(EXIT_FAILURE);
}
}
int main(int argc, char *argv[])
{
int sock;
struct sockaddr_in serverName;
char hostName[hostNameLength];
char messageString[messageLength];
char buffer[1024];
if(argv[1] == NULL)
{
perror("Usage: client [host name]\n");
exit(EXIT_FAILURE);
}
else
{
strncpy(hostName, argv[1], hostNameLength);
hostName[hostNameLength - 1] = '\0';
}
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("Could not create a socket\n");
exit(EXIT_FAILURE);
}
initSocketAddress(&serverName, hostName, PORT);
if(connect(sock, (struct sockaddr *)&serverName, sizeof(serverName)) < 0)
{
perror("Could not connect to server\n");
exit(EXIT_FAILURE);
}
printf("\nType something and press [RETURN] to send it to the server.\n");
printf("Type 'quit' to nuke this program.\n");
fflush(stdin);
recv(sock, buffer, 1024, 0);
printf(buffer);
while(1)
{
printf("\n>");
fgets(messageString, messageLength, stdin);
messageString[messageLength - 1] = '\0';
if(strncmp(messageString, "quit\n",messageLength) != 0)
writeMessage(sock, messageString);
if(recv(sock, buffer, 1024, 0) > 0)
printf(buffer);
}
}
您需要对代码进行几处更改才能使其正常工作。你没有收到任何东西的原因是你的客户陷入了困境
fgets(messageString、messageLength、stdin);这是一个阻塞调用,所以只需在客户端创建一个用于接收消息的线程,这样它就可以连续监听。对代码进行以下更改,它将帮助您实现您的结果。
在代码的客户端添加以下行:
客户C
void * receiveMessage(void * socket)
{
int sockfd, ret;
char buffer[1024];
sockfd = (int) socket;
int count = 1;
memset(buffer, 0, 1024);
for (;;)
{
if (recvfrom(sockfd, buffer, 1024, 0, NULL, NULL) > 0)
{
fputs(buffer, stdout);
printf("\n");
}
}
}
在main函数中添加以下行
//creating a new thread for receiving messages from the server
read = pthread_create(&rThread, NULL, receiveMessage, (void *) sock);
if (read < 0)
{
printf("ERROR: Return Code from pthread_create() is %d\n", read);
exit(1);
}
并在循环时更改为以下
while(1)
{
printf("\n>");
fgets(messageString, messageLength, stdin);
messageString[messageLength - 1] = '\0';
if(strncmp(messageString, "quit\n",messageLength) != 0)
{
writeMessage(sock, messageString);
}
}
server. c(在连接处理程序中添加广播消息)
void *connection_handler(void *socket_desc)
{
int sock = *(int*)socket_desc;
int read_size;
char *message, client_message[2000], *message_to_client;
char broadcast[50] = "new client connected";
int num;
num = sock;
num--;
while(num > 3)
{
write(num, broadcast, strlen(broadcast));
sleep(1);
num--;
}
while((read_size = recv(sock, client_message, 2000, 0)) > 0)
{
client_message[read_size] = '\0';
printf("Client[%d]: %s", sock, client_message);
message_to_client = "I hear you dude...";
write(sock, message_to_client, strlen(message_to_client));
memset(client_message, 0, 2000);
}
if(read_size == 0)
{
printf("Client[%d] disconnected", sock);
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
free(socket_desc);
return 0;
}
我试图用java实现一个客户端服务器,在这里我读取客户端中的输入并在服务器中执行UperCase,然后返回客户端并打印UperCase。我使用ObjectOutputStream和ObjectInputStream进行读写,但是当我在客户机中键入一个msg时,程序会显示以下错误: Digite uma msg casa java.io.eofexception位于java.io.datainput
真的需要你帮忙。 我的项目是通过电缆连接两台PC机,并使用tcp套接字将客户端文本框形式的字符串发送到服务器。问题是ATI只能发送一个字符串,然后连接就会关闭。 注意:某个端口上的连接将在表单加载中建立并成功。
我对套接字有点陌生,我正在尝试编写一个程序,在这个程序中,我基本上可以从客户端程序向服务器程序发送一些简单的请求。现在我只想在客户端有1或2个选项供用户选择。例如,如果用户在客户端选择“选项1”,那么服务器会返回一条消息“您选择选项1”,以此类推,但我不知道如何读取服务器上从客户端发送的输入。 客户代码: 服务器代码: 我需要在Clinet中使用两个不同的BufferedReader吗?一个用于用
正在编写一个服务器,使用Java套接字的客户端聊天程序。这是我的服务器套接字类的代码。 客户端能够建立连接并向服务器发送消息。服务器也可以接收客户端发送的消息。问题是当消息从服务器发送时,客户端没有收到消息。这是我的客户端套接字代码。
Java: 在C#中-它停止在“receiver=listener.accept();”在java(android)中-它停止于“sender_socket=new Socket(serverAddr,SERVERPORT);”这应该是java套接字函数的问题--需要另一个函数连接到C#-server。
问题内容: 我试图用没有gui的服务器连接带有gui的客户端。连接已完成,但我看不到这两个应用程序之间的任何消息。(我应该在客户端中找到SERVER HERE,在服务器中找到CLIENT HERE) 客户端连接代码: (输入和输出在此客户端类扩展到的GUI类中定义。定义为“受保护的BufferedReader输入;受保护的PrintWriter输出;”) 另外,服务器代码: 连接似乎还可以,所以我