C 套接字通信与字符串连接
亲爱的各位, 我正在尝试实现一个客户机-服务器模型,客户机尝试接受用户输入,将消息发送到服务器,然后服务器追加“从服务器回显:”+(客户机消息)并发送回服务器,但我使用以下代码未成功,有人能帮我一个忙吗?我在这里花了很多时间:( 客户C 套接字通信与字符串连接,c,rpc,C,Rpc,亲爱的各位, 我正在尝试实现一个客户机-服务器模型,客户机尝试接受用户输入,将消息发送到服务器,然后服务器追加“从服务器回显:”+(客户机消息)并发送回服务器,但我使用以下代码未成功,有人能帮我一个忙吗?我在这里花了很多时间:( 客户 /* * Usage: sender [host] * * General description of code: * (1) Create a local socket, specifying domain and protocol *
/*
* Usage: sender [host]
*
* General description of code:
* (1) Create a local socket, specifying domain and protocol
* (2) Set up the remote address
* (3) Connect to it
* (4) Send/recv data to server
* (5) Close connection
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#define PORT 5667
main(argc, argv)
int argc;
char *argv[];
{
int s;
struct hostent *remote_ent;
struct sockaddr_in remote_addr;
char ch[40];
if (argc != 2) {
printf("usage: sender hostname \n"); exit(1);
}
/* (1) Create the socket */
if ((s = socket(AF_INET,SOCK_STREAM,0)) < 0) {
perror("Can't create send_socket"); exit(1);
}
/* (2) Assign the remote address */
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(PORT);
if ((remote_ent = gethostbyname(argv[1])) == NULL) {
perror("Can't get remote host address"); exit(1);
}
bcopy(remote_ent->h_addr_list[0],
&remote_addr.sin_addr, remote_ent->h_length);
/* (3) Connect to remote socket */
if (connect(s, &remote_addr, sizeof(remote_addr)) < 0) {
perror("Can't connect to remote address"); exit(1);
}
/* (4) Send /recv data thru socket */
while ((gets(ch)) != ".") {
if (write(s, ch, 40) < 0) {
perror("write error"); exit(1);
}
read(s, ch, 1);
puts(ch);
}
/* (5) Close and exit */
close(s); /* close remote socket as well */
exit(0);
}
/*
*用法:发送方[主机]
*
*代码的一般说明:
*(1)创建本地套接字,指定域和协议
*(2)设置远程地址
*(3)连接到它
*(4)向服务器发送/接收数据
*(5)紧密连接
*/
#包括
#包括
#包括
#包括
#包括
#定义端口5667
主(argc、argv)
int-argc;
char*argv[];
{
int-s;
结构主机*远程设备;
远程地址中的结构sockaddr\u;
char-ch[40];
如果(argc!=2){
printf(“用法:发送方主机名”);退出(1);
}
/*(1)创建套接字*/
if((s=socket(AF\u INET,SOCK\u STREAM,0))<0){
perror(“无法创建发送_套接字”);退出(1);
}
/*(2)分配远程地址*/
远程地址sin家庭=AF网络;
远程地址sin\u端口=htons(端口);
if((remote_ent=gethostbyname(argv[1]))==NULL){
perror(“无法获取远程主机地址”);退出(1);
}
b复制(远程内容->地址列表[0],
&远程地址:sin地址,远程地址->h\U长度);
/*(3)连接到远程插座*/
if(连接(s,&remote\u addr,sizeof(remote\u addr))<0){
perror(“无法连接到远程地址”);退出(1);
}
/*(4)通过插座发送/接收数据*/
while((get(ch))!=“){
如果(写入(s,ch,40)<0){
perror(“写入错误”);退出(1);
}
读(s,ch,1);
看跌期权(ch);
}
/*(5)关闭并退出*/
关闭;/*同时关闭远程插座*/
出口(0);
}
服务器
/*
* receiver.c
*
* Receiver (server) half of a pair of sockets.
* Note: receiver is already multi-threading!
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#define PORT 5667 /* by Kei */
main() {
int s, new_s;
int remote_addr_len;
struct sockaddr_in local_addr, remote_addr;
char ch[40];
char *ch2 = "Echoed from server:";
/* (1) Create the socket */
if ((s = socket(AF_INET,SOCK_STREAM,0)) < 0) {
perror("Can't create s");
exit(1);
}
bzero(&local_addr,sizeof(local_addr));
/* (2) Set up the address */
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(PORT); /* port#, no need of IP addr */
/* (3) Bind local address to this socket */
if (bind(s, &local_addr, sizeof(local_addr)) < 0) {
perror("Can't bind socket to local address"); exit(1);
}
/* (4) Wait for a connection (only 1 pending allowed)*/
if (listen(s, 1) < 0) {
perror("listen failed"); exit(1);
}
while (1) { /* wait for connection, recv and reply */
/* (5) Accept connection */
if ((new_s = accept(s, &remote_addr, &remote_addr_len))<0) {
perror("Can't accept connection"); exit(1);
}
/* IP-addr & port # of the remote socket */
printf("remote IP: %d.%d.%d.%d\n",
remote_addr.sin_addr._S_un._S_un_b.s_b1,
remote_addr.sin_addr._S_un._S_un_b.s_b2,
remote_addr.sin_addr._S_un._S_un_b.s_b3,
remote_addr.sin_addr._S_un._S_un_b.s_b4);
printf("remote port: %d\n", remote_addr.sin_port);
/* (6) Exchange data. Socket is Bi-directional! */
while (read(new_s, ch, 40) > 0) {
strcat(ch2,ch);
if (write(new_s, ch2, 40) < 0) {
perror("write error"); exit(1); }
puts(ch); /* put on screen */
}
close(new_s);
}
/* (7) Close and exit */
close(s);
exit(0);
}
/*
*接收机c
*
*接收器(服务器)一对套接字的一半。
*注意:接收器已经是多线程的!
*/
#包括
#包括
#包括
#包括
#包括
#通过Kei定义端口5667/**/
main(){
国际标准,新标准;
国际远程地址;
本地地址、远程地址中的结构sockaddr\u;
char-ch[40];
char*ch2=“从服务器回显:”;
/*(1)创建套接字*/
if((s=socket(AF\u INET,SOCK\u STREAM,0))<0){
perror(“无法创建s”);
出口(1);
}
bzero(&local_addr,sizeof(local_addr));
/*(2)设置地址*/
本地地址sin家庭=AF\u INET;
local_addr.sin_port=htons(port);/*port#,不需要IP地址*/
/*(3)将本地地址绑定到此套接字*/
if(绑定本地地址,大小(本地地址))<0{
perror(“无法将套接字绑定到本地地址”);退出(1);
}
/*(4)等待连接(仅允许1个挂起)*/
如果(听(s,1)<0){
perror(“侦听失败”);退出(1);
}
而(1){/*等待连接,recv和reply*/
/*(5)接受连接*/
如果((新地址=接受(远程地址和远程地址))0){
strcat(ch2,ch);
如果(写入(新的,ch2,40)<0){
perror(“写入错误”);退出(1);}
将(ch);/*放在屏幕上*/
}
关闭(纽约);
}
/*(7)关闭并退出*/
关闭(s);;
出口(0);
}
您的程序有几个问题,我可以马上看到
receiver.c
中,您使用字符串文本作为第一个参数调用strcat()
——尝试修改字符串文本会导致未定义的行为。即使您成功地修改了字符串文本,您也不会在再次执行循环之前重置它——您的输出不会像您想要的那样sender.c
中,您试图将字符串与=
运算符(调用get()
和“
的结果)进行比较。这不起作用。请使用strcmp()
gets()
-它很容易出现缓冲区溢出。fgets()
可以安全使用-试试看sender.c
程序在尝试从服务器获取回显时仅读取1个字节。您需要尝试接收要获取的整个字符串虽然你没有说你遇到了什么样的问题,但有一个问题是相当明显的:
while ((gets(ch)) != ".") {
if (write(s, ch, 40) < 0) {
“但我不成功”是什么意思?错误消息?崩溃?糟糕的输出?我认为
strcmp()
调用也需要\n
,因为fgets()
将把它包含在返回的字符串中。@Carl Norum:不——这不是strtok
的“奇怪但有用的目的”——去掉尾部“\n”是的,我理解,但是调用在while
循环体中。循环将如何结束?
while (fgets(ch, sizeof(ch), stdin) && strcmp(ch, ".\n")) {
strtok(ch, "\n"); // the oddball but useful purpose for `strtok`.
if (write(s, ch, strlen(ch))<0) {
// ...