C套接字-消息只发送一次
我正在尝试创建一个只在共享内存中包含文件的小文件服务器。客户端应该向服务器发送创建、删除等命令。但是,我还没有到那个阶段 我准备了一个服务器和一个客户端。服务器接受一个套接字,并为每个客户端连接创建一个新线程(需求) 当我启动客户端时,我可以成功地连接到服务器并发送一条将被接收的消息。然而,这只起作用一次。发送我的命令后,服务器将不会接收任何其他命令 我试着用断线器捕捉信息,但这似乎不起作用,所以任何帮助都将不胜感激 提前谢谢 服务器源:C套接字-消息只发送一次,c,sockets,C,Sockets,我正在尝试创建一个只在共享内存中包含文件的小文件服务器。客户端应该向服务器发送创建、删除等命令。但是,我还没有到那个阶段 我准备了一个服务器和一个客户端。服务器接受一个套接字,并为每个客户端连接创建一个新线程(需求) 当我启动客户端时,我可以成功地连接到服务器并发送一条将被接收的消息。然而,这只起作用一次。发送我的命令后,服务器将不会接收任何其他命令 我试着用断线器捕捉信息,但这似乎不起作用,所以任何帮助都将不胜感激 提前谢谢 服务器源: /* * main.c - the server fi
/*
* main.c - the server file.
*
* Created on: Apr 26, 2014
* Author: fish-guts
*/
#include "main.h"
/* our main server buffer */
char serverbuf[4096];
static int client_sock;
void launch_app(char *argv[]) {
if ((strcmp(argv[1], "start")) == 0)
startup();
else if ((strcmp(argv[1], "stop")) == 0)
stop_server();
else {
fprintf(stderr,
"Invalid Command: %s. Valid Commands are ./fileserver [start|stop]\n",
argv[1]);
exit(EXIT_FAILURE);
}
}
int main(int argc, char* argv[]) {
if (argc > 1)
launch_app(argv);
else {
fprintf(stderr,
"No argument supplied. Valid Argument are [start|stop]\n");
exit(EXIT_SUCCESS);
}
return 0;
}
void print_start_msg(void) {
fprintf(stderr, "###############################\n");
fprintf(stderr, "Welcome to Severin'ŝ FileServer\n");
fprintf(stderr, "###############################\n");
}
void stop_server(void) {
exit(EXIT_SUCCESS);
}
void startup(void) {
print_start_msg();
start_server();
}
void start_server(void) {
int s, len, rc;
int tid;
long t;
char buf[100000];
struct sockaddr_in addr;
struct sockaddr_in client;
pthread_t client_thread;
sock = socket(AF_INET, SOCK_STREAM, 0);
unsigned short port = PORT;
// clear the struct
memset((char*) &addr, 0, sizeof(addr));
fprintf(stderr, "\n\nStarting server...");
// let's set some values
/* type of socket created in socket() */
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons((unsigned short) PORT);
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
/* bind the socket to the port specified above */
if ((rc = bind(sock, (struct sockaddr *) &addr, sizeof(addr))) < 0) {
fprintf(stderr, "Error binding address: %s\n", strerror(errno));
exit(EXIT_FAILURE);
} else {
fprintf(stderr, "Bind Successful\n");
}
if ((listen(sock, serverbuf) < 0)) {
fprintf(stderr, "Listen Failed\n");
exit(EXIT_FAILURE);
} else {
fprintf(stderr, "Server started successfully, listening on port %d\n",
PORT);
}
// the main server loop
while (!quitting) {
len = sizeof(struct sockaddr_in);
client_sock = accept(sock, (struct sockaddr *) &client, &len);
if (client_sock < 0) {
fprintf(stderr, "Accept failed\n");
} else {
/* This is the client process */
tid = pthread_create(&client_thread, NULL, doprocessing, (void*) t);
if (tid) {
fprintf(stderr, "Error creating thread: %d\n", tid);
}
}
}
}
void *doprocessing(void) {
int n;
int s, len, rc;
char buf[100000];
char *str = "Welcome\n";
bzero(buf, 100000);
n = write(client_sock, str, sizeof(str));
if (n < 0) {
fprintf(stderr, "ERROR writing to socket");
exit(1);
}
s = recv(client_sock, buf, sizeof(serverbuf),0);
if (s) {
fprintf(stderr,"Bytes received: %i\n",s);
buf[s] = 0;
// we use CRLF as a line breaker, its easier to parse the commands
char *pch = strtok(buf, "\n");
while (pch != NULL) {
strcpy(serverbuf, pch);
fprintf(stderr, "Command: %s\n", buf);
//TODO: add command handler
//parse();
serverbuf[s] = 0;
pch = strtok(NULL, "\r\n");
//addlog(1, serverbuf);
}
} else {
fprintf(stderr,"No data received\n");
}
}
/*
*main.c-服务器文件。
*
*创建日期:2014年4月26日
*作者:鱼内脏
*/
#包括“main.h”
/*我们的主服务器缓冲区*/
char-serverbuf[4096];
静态int客户端_sock;
无效启动应用程序(char*argv[]){
如果((strcmp(argv[1],“start”)==0)
启动();
否则如果((strcmp(argv[1],“stop”)==0)
停止服务器();
否则{
fprintf(标准,
“无效命令:%s。有效命令为./fileserver[start | stop]\n”,
argv[1]);
退出(退出失败);
}
}
int main(int argc,char*argv[]){
如果(argc>1)
启动应用程序(argv);
否则{
fprintf(标准,
“未提供参数。有效参数为[start | stop]\n”);
退出(退出成功);
}
返回0;
}
无效打印\u开始\u消息(无效){
fprintf(stderr,“#############################;
fprintf(stderr,“欢迎使用Severin'ŝFileServer\n”);
fprintf(stderr,“#############################;
}
void停止服务器(void){
退出(退出成功);
}
无效启动(无效){
打印_start_msg();
启动服务器();
}
void启动服务器(void){
内特s,len,rc;
国际贸易署;
长t;
char buf[100000];
地址中的结构sockaddr\u;
客户端中的结构sockaddr_;
pthread_t client_线程;
sock=socket(AF\u INET,sock\u STREAM,0);
无符号短端口=端口;
//清除结构
memset((char*)&addr,0,sizeof(addr));
fprintf(stderr,“\n\n正在启动服务器…”);
//让我们设定一些值
/*在套接字()中创建的套接字类型*/
addr.sin_family=AF_INET;
addr.sin\u addr.s\u addr=INADDR\u ANY;
地址sin_端口=htons(无符号短端口);
inet_-pton(AF_-inet,“127.0.0.1”和地址sin_-addr);
/*将套接字绑定到上面指定的端口*/
if((rc=bind(sock,(struct sockaddr*)和addr,sizeof(addr)))<0){
fprintf(stderr,“错误绑定地址:%s\n”,strerror(errno));
退出(退出失败);
}否则{
fprintf(stderr,“绑定成功”\n);
}
if((侦听(sock,serverbuf)<0)){
fprintf(stderr,“侦听失败\n”);
退出(退出失败);
}否则{
fprintf(stderr,“服务器已成功启动,正在侦听端口%d\n”,
港口);
}
//主服务器循环
当(!退出){
len=sizeof(结构sockaddr_in);
client_sock=accept(sock,(struct sockaddr*)和client,&len);
如果(客户_sock<0){
fprintf(stderr,“接受失败\n”);
}否则{
/*这是客户端进程*/
tid=pthread\u create(&client\u thread,NULL,doprocessing,(void*)t);
若有(工业贸易署){
fprintf(stderr,“创建线程时出错:%d\n”,tid);
}
}
}
}
void*数据处理(void){
int n;
内特s,len,rc;
char buf[100000];
char*str=“欢迎\n”;
B0(10万南非法郎);
n=写入(客户机_sock,str,sizeof(str));
if(n<0){
fprintf(stderr,“写入套接字时出错”);
出口(1);
}
s=recv(客户机容量,buf,sizeof(服务器容量),0);
若有(s){
fprintf(stderr,“接收的字节数:%i\n”,s);
buf[s]=0;
//我们使用CRLF作为换行符,这样更容易解析命令
char*pch=strtok(buf,“\n”);
while(pch!=NULL){
strcpy(serverbuf,pch);
fprintf(stderr,“命令:%s\n”,buf);
//TODO:添加命令处理程序
//parse();
serverbuf[s]=0;
pch=strtok(空,“\r\n”);
//addlog(1,serverbuf);
}
}否则{
fprintf(stderr,“未收到数据”);
}
}
客户资料来源:
#include "main.h"
#define PORT 8083
#define BUF_SIZE 1024
int quitting;
void start_client(const char *address);
int main(int argc, char* argv[]) {
start_client("localhost");
}
void start_client(const char *address) {
struct hostent *he;
struct sockaddr_in server;
int s;
char buf[BUF_SIZE];
char input[BUF_SIZE];
sock = socket(AF_INET, SOCK_STREAM, 0);
if ((he = gethostbyname(address)) == NULL) {
fprintf(stderr,"error resolving hostname..");
exit(1);
}
/*
* copy the network address part of the structure to the
* sockaddr_in structure which is passed to connect()
*/
memcpy(&server.sin_addr, he->h_addr_list[0], he->h_length);
server.sin_family = AF_INET;
server.sin_port = htons((unsigned short)PORT);
/* connect */
if (connect(sock, (struct sockaddr *) &server, sizeof(server))) {
puts("Error connecting...\n");
exit(1);
} else {
fprintf(stderr,"Connected to server\n");
}
send(sock,"Hallo Server\n",BUF_SIZE,0);
int i = 0;
while(!quitting) {
if(i<100) {
send(sock,"yallo",6,0);
}
fgets(input, sizeof(input), stdin);
if(send(sock,input,strlen(input),0)<0) {
fprintf(stderr,"Error sending data: %s\n",errno);
} else {
fprintf(stderr,"Hello: %s\n",buf);
}
s = recv(sock, buf, sizeof(buf),0);
if(s) {
buf[s] = 0;
fprintf(stderr,"Message from Server: %s\n",buf);
} else {
fprintf(stderr,"Error in recv: %s\n",errno);
}
}
}
#包括“main.h”
#定义端口8083
#定义BUF_大小1024
戒烟;
无效启动_客户端(常量字符*地址);
int main(int argc,char*argv[]){
启动_客户端(“本地主机”);
}
无效启动_客户端(常量字符*地址){
结构宿主*he;
服务器中的结构sockaddr_;
int-s;
字符大小[buf_SIZE];
字符输入[BUF_大小];
sock=socket(AF\u INET,sock\u STREAM,0);
如果((他=gethostbyname(地址))==NULL){
fprintf(stderr,“错误解析主机名…”);
出口(1);
}
/*
*将结构的网络地址部分复制到
*传递给connect()的结构中的sockaddr_
*/
memcpy(&server.sinu addr,he->h\u addr\u list[0],he->h\u length);
server.sinu family=AF\u INET;
server.sin_port=htons((无符号短)端口);
/*连接*/
if(连接(sock,(struct sockaddr*)和服务器,sizeof(服务器))){
puts(“连接错误…\n”);
出口(1);
}否则{
fprintf(stderr,“已连接到服务器\n”);
}
发送(sock,“Hallo Server\n”,基本大小,0);
int i=0;
当(!退出){
当处理套接字时,如果(i很少有规则:
1.低级消息字段定义
请始终记住,您正在对字节流进行读写操作。另一条规则是,TCP/IP不能保证一次写入等于一次读取。但是,这些规则对您意味着什么
上述规则的组合意味着您必须准确地知道从套接字读取前需要读取多少字节。因此:
(案例1):
int myInt = 12345;
send(sockfd, &myInt, sizeof(myInt), my_flags);
int myReceivedInt = 0;
int received_count = recv(client_sock, &myReceivedInt, sizeof(myReceivedInt), 0);
// get string length
int str_size = strlen(my_str);
// send fixed-length data to pre-pend variable-length field with the latter's size
send(sockfd, &str_size, sizeof(str_size), my_flags);
// send the variable-length field.
send(sockfd, my_str, str_size, my_flags);
int string_size = 0;
char *received_string = NULL;
int received_count = recv(client_sock, &string_size, sizeof(string_size), 0);
/*
now we know how big the string is, so we allocate
memory for it or use a previously allocated buffer. This is omitted...
*/
int received_count = recv(client_sock, &received_string, string_size, 0);
received_string[string_size] = '\0';
int file_size = 0, read_so_far = 0, ret = 0;
recv(sockfd, &file_size , sizeof(file_size), 0);
// now we know how big is the file...allocate buffer (file_content) and read file fully
while(read_so_far != file_size)
{
ret = recv(sockfd, file_content + read_so_far, file_size - read_so_far, 0);
if(ret < 0)
{
// handle error case, socket reset maybe?
perror("Something bad happened with the socket");
break;
}
read_so_far += ret;
}
char command = 0;
s = recv(client_sock, &command, 1,0);
if(command == LIST_NODES_COMMAND)
{
// read arguments for command and process it.
} else if(command == CREATE_FOLDER_COMMAND)
{
// read arguments for command and process it.
}
while(1)
{
char command = 0;
s = recv(client_sock, &command, 1,0);
if(command == LIST_NODES_COMMAND)
{
// handle list command here.
} else if(command == CREATE_FOLDER_COMMAND)
{
// read params like above and handle command.
} else if (command == COMMAND_QUIT)
{
// do the stuff necessary before the client disconnects.
}
}