我有一个用C创建的简单套接字程序(使用Ubuntu),连接正常,服务器编译,客户端提供IP和端口号。
但是建立连接后,客户端只能send one message
,然后只能connection closes
。当客户端发送消息时,服务器会收到消息并发送程序ends by itself
。
我尝试使用while loop
,但它给了我一个Error on binding
。有没有办法让它无限,所以当用户输入exit
或某些specific key/command
时,程序就会结束。
server.c UPDATED with WHILE LOOP
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portNum, clien, n;
char buffer[256];
struct sockaddr_in serv_addr,cli_addr;
if (argc < 2)
{
fprintf(stderr, "\nno port provided");
exit(1);
}
sockfd = socket(AF_INET,SOCK_STREAM, 0);
if (sockfd < 0)
printf("\nprovide a valid port number\n");
bzero((char *)&serv_addr, sizeof(serv_addr));
portNum = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portNum);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
printf("error on binding");
while(1)
{
listen(sockfd,5);
}
clien = sizeof(cli_addr);
newsockfd=accept(sockfd, (struct sockaddr *) &cli_addr, &clien );
if (newsockfd < 0)
printf("=> Error on accepting...\n");
bzero(buffer, 256);
n = read(newsockfd, buffer, 256);
if (n < 0)
printf("error reading from socket...\n");
printf("%s\n", buffer);
n = write(newsockfd, "message received.", 58);
if (n < 0)
printf("cannot write from socket...\n");
return 0;
}
client.c UPDATED with WHILE LOOP
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
int main(int argc, char *argv[])
{
int sockfd,portno,n;
char buffer[256];
struct sockaddr_in serv_addr;
struct hostent *server;
//while(counter != 5)
// /{
if (argc < 3)
{
fprintf(stderr,"Usage %s hostname port...\n",argv[0]);
exit(1);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
printf("\error opening socket...\n");
bzero((char *) &serv_addr, sizeof(serv_addr));
server = gethostbyname(argv[1]);
if (server == NULL)
{
fprintf(stderr,"no such host...\n");
exit(0);
}
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd, &serv_addr,sizeof(serv_addr)) <0 )
printf("\error connecting\n");
printf("your message:");
fgets(buffer, 256, stdin);
while(1)
{
n = write(sockfd,buffer,strlen(buffer));
}
if (n < 0)
printf("error writing to socket\n");
n = read(sockfd, buffer, 255);
if (n < 0)
printf("error reading from socket\n");
printf("%s\n", buffer);
return 0;
}
谢谢。
答案 0 :(得分:2)
您的服务器的问题是您在收到消息时立即终止。你应该做的是继续使用recv()函数进行监听,直到客户端断开连接。这是一段应该做的诀窍。
免责声明:不过我还没有测试过它,它来自我为你修改的旧项目,它应该可以工作但是我不是百分之百确定它,我现在没时间测试它但如果出现问题,请随时提问,我会尽力纠正。
编辑:尝试重新生成导致错误,因为绑定已经完成且端口已经忙,所以你不能“分配”另一个程序到这个端口,因此给你一个错误。您唯一需要做的就是确保服务器监听,直到客户端与服务器断开连接。此外,有些代码可能是在某些时候为c ++编写的,但网络部分应该可以正常工作。
如果您有任何疑问,请随意尝试并发表评论。 Server.c:
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
//HANDLE ERROR
}
printf("Socket created\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8000 );
//Binding, you already do it correctly.
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server))< 0)
{
//ERROR
}
printf("bind done");
//Listen
listen(socket_desc , 3);
printf("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
{
puts("Connection accepted");
pthread_t sniffer_thread;
new_sock = (int*) malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
//ERROR
}
printf("Handler assigned");
}
if (client_sock < 0)
{
//ERROR
}
//return 0;
}
/*
* This will handle connection for each client you may have and read indefinitely
* */
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int read_size;
char *message , client_message[2000];
string smatrix ;
int ind ;
string tok ;
int i = 0 ;
//Receive a message from client
while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
{
//What you want to do with the client's message
}
if(read_size == 0)
{
printf("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
//ERROR
}
//Free the socket pointer
free(socket_desc);
对于客户端,执行while循环直到某个时间过去或输入给定的字符或值。类似的东西:
while(wantToExit == false){
char a;
printf("Please enter a char");
scanf("%c", &a);
write(sock , a , 1); //Note use strlen() for strings
}
希望有所帮助
答案 1 :(得分:1)
您实际期望服务器做什么?你打开/读/终止。终止,当然会隐式关闭套接字 - 幸运的是,当你忘记明确关闭时。
你必须经常从套接字读取。不确定你的意思是“它...给我一个关于绑定的错误”;如果你试图重新绑定,那当然是错的。你不会一次又一次地打开文件,只是为了阅读它的数据。
如果您希望在从另一侧关闭套接字之后监听套接字,则只需在外部循环中使用listen
。
阅读维基百科,了解有关sockets的基础知识并查看链接。