我用C创建了一个简单的套接字程序(使用Ubuntu),连接工作正常,服务器编译和客户端提供IP和端口号。
但连接建立后,客户端只能访问send one message
,然后访问connection closes
。当客户端发送消息时,服务器接收消息,程序ends by itself
。
我试图使用while loop
,但它给了我一个Error on binding
。是否有办法使其无限,以便当用户输入exit
或某些specific key/command
时,程序结束。
server.c更新了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 numbern");
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("%sn", buffer);
n = write(newsockfd, "message received.", 58);
if (n < 0)
printf("cannot write from socket...n");
return 0;
}
client.c更新了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 connectingn");
printf("your message:");
fgets(buffer, 256, stdin);
while(1)
{
n = write(sockfd,buffer,strlen(buffer));
}
if (n < 0)
printf("error writing to socketn");
n = read(sockfd, buffer, 255);
if (n < 0)
printf("error reading from socketn");
printf("%sn", buffer);
return 0;
}
谢谢。
服务器的问题是,只要收到消息,就会立即终止。您应该做的是使用recv()函数继续侦听,直到客户端断开连接。这里有一段代码应该可以做到这一点。
免责声明:然而,我还没有测试过它,它是从一个旧的项目,我修改了你在飞行它应该工作,但我不是100%肯定,我没有时间测试它现在,但随时问问题,如果有什么错误,我会尽量纠正它。
编辑:尝试重新绑定会导致错误,因为绑定已经完成,端口已经很忙,所以你不能"分配"其他程序到这个端口,因此给你一个错误。您唯一要做的就是确保您的服务器一直侦听,直到客户端与服务器断开连接。
同样,有些代码可能是为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 createdn");
//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
}
希望有所帮助
您实际期望服务器做什么?你打开/阅读/终止。当然,终止会隐式地关闭套接字——幸运的是,您忘记显式地关闭了。
必须不断地从套接字读取。不知道你说的"它"是什么意思。给我一个绑定错误";如果你试图重新绑定,那当然是错误的。你不会一次又一次地打开一个文件,然后……读取它的数据。
如果您想在套接字从另一端关闭后侦听它,只需将listen
置于外部循环中。
阅读维基百科关于套接字的基础知识,并检查链接。